/**
 * 排版引擎
 * @param {*} painter 渲染引擎
 * @param {*} newPage 页面对象
 * @param {*} ratio 文本缩放比
 * @param {*} opt 可选参数 { pageRect:页面包围盒, zoomScale:页面缩放比 }
 */
function sLayoutEngine(painter, newPage, ratio, opt) {
    opt = opt ? opt : {};

    const FONT_ASCENT = "fontBoundingBoxAscent";
    const FONT_DESCENT = "fontBoundingBoxDescent";

    var DRIFT_LEN = 0.5;

    var page = null;
    var pageIndex = -1;

    var scale = ratio ? ratio : 1;
    var setting = opt.setting ? opt.setting : {};

    /**
     * 偏移量工具
     */
    var ost = new sOffsetUtil();

    /**
      * 转换工具
      */
    var converter = new sConverter();

    //设置文本缩放比
    painter.setScale(scale);
    //设置分页对象
    painter.setPage(newPage);
    //设置图层对象
    painter.setPaintLayer(opt.plm);
    //设置全局配置对象
    painter.setSetting(setting);
    
    /**
     * 获取渲染引擎
     */
    this.getPainter = function(){
        return painter;
    }

    /**
     * 关联一个分页对象
     * @param {*} page 分页对象
     * @param {*} callback 关联之后调用该回调函数
     */
    this.bindPage = function(newPage, callback){
        page = newPage;

        if(page){
            //页面包围盒
            var pageRect = opt.pageRect
                ? opt.pageRect
                : painter.getSize();
                
            //页面缩放比
            var zoomScale = opt.zoomScale 
                ? opt.zoomScale
                : 1;
            
            pageRect.width /= zoomScale;
            pageRect.height /= zoomScale;

            page.setBoundRect(pageRect);

            pageIndex = page.getIndex();
        }

        if(callback){
            callback(page);
        }
    }

    this.bindPage(newPage);

    /**
     * 获取绑定的分页对象
     * @returns 
     */
    this.getPage = function() {
        return page;
    }

    /**
     * 文本排版
     * @param {*} text sText文本元素
     * @param {*} parentRect 父级的包围盒信息
     * @param {*} type 页面布局类型：body(页体,默认) head(页眉) foot(页脚) 
     * @param {*} option 可选项
     * @returns 返回值如下：
     * 0 无需新增分页
     * 1 需新增分页且当前文本不在当前页 
     * 2 需新增分页，当前文本元素会被分割到当前页和新增页
     */
    this.textFormat = function (text, parentRect, type, option) {
        if(ifHiddenThenAdd(text, type)) return;

        //根据段落样式设置父级包围盒
        parentRect = setParentRectByParagraph(type, text, parentRect);

        //上一行的挂载元素
        if(text.__attachElements){
            reformatAttachElement(text.__attachElements, this, type);
            delete text.__attachElements;
        }

        var newpage = 0;
        var metrics = supOrSubAlignMutation.call(this, text);

        painter.setStyle({
            fillStyle: text.style.color,
            font: text.getFontStyle(scale)
        });

        //优先取剩余文本(之前页排版多出的内部文本)，其次取内部文本，最后取背景文本
        var innerText = getTextElementContent(text);
        var pageRect = {...page.getBoundRect(type, true)};
        
        pageRect.width = parentRect.width;

        //跨页的文本
        if(text.__end || text.__end == 0){
            var startPos = parentRect;
            var textList = splitText.call(
                this, 
                innerText.substr(text.__end), 
                startPos,
                parentRect,
                pageRect, 
                1,
                text
            );
            return procSplitText.call(this, text, textList, type);
        }

        var textMetrics = painter.measureCurText(innerText, text);
        var boundRect = {
            top: 0,
            left: 0,
            width: textMetrics.width,
            height: textMetrics[FONT_ASCENT] + textMetrics[FONT_DESCENT],
            textMetrics: textMetrics,
            FONT_ASCENT: FONT_ASCENT,
            FONT_DESCENT: FONT_DESCENT
        }

        if(metrics){
            if(metrics.mutationHeight){
                boundRect.mutationHeight = metrics.mutationHeight;
            }else{
                boundRect.mutationHeight = metrics[FONT_ASCENT] + metrics[FONT_DESCENT];
            }
        }

        if(text.__remainText == null){
            //根据情况插入新行
            insertRowIfNeed.call(this, text, type);
        }

        //计算放入当前行之后文本的包围盒
        var measureRect = page.getLastRow(type).measureText(boundRect, text);
        
        //起始左边距溢出
        if(measureRect.left > pageRect.left + pageRect.width){
            measureRect = page.insertRow(type).measureText(boundRect, text);
        }else if(innerText && innerText.length > 0){
            //第一个文本字符溢出
            textMetrics = painter.measureCurText(innerText.substr(0, 1));
            if(measureRect.left + textMetrics.width > pageRect.left + pageRect.width){
                //当前行存在可见元素
                if(page.getLastRow(type).getLastVisibleElement()){
                    measureRect = this.getPage().insertRow(type).measureText(boundRect, text);
                }
            }
        }

        //宽度溢出
        if (measureRect.left + measureRect.width > pageRect.left + pageRect.width) {
            newpage = procWidthFormat.call(this, text, measureRect, parentRect, type, option);
        }else{
            //是否高度溢出
            var exceed = isExceed.call(this, measureRect, text, type);

            if(exceed > 1 && (!option || !option.ignoreExceed)){
                if(exceed == 2 && page.getLastRow(type).getIndex() > 1){
                    //只是高度溢出，则将当前行所有元素带到下一行
                    text.__attachElements = page.getLastRow(type).getElementList();
                    deleteBoundAttachElement(text.__attachElements, type);
                    page.removeLastRow(type);
                }else{
                    if(page.getLastRow(type).isEmpty()){
                        page.getLastRow(type).removeParagraphOnlyRelFor(text);
                        page.removeLastRow(type);
                    }
                }

                return 1;
            }else if(exceed < 0){
                return 0;
            }

            var pageIndex = page.getIndex();
            var index = page.getLastRow(type).getIndex();

            if(text.__remainText == null){
                text.__boundRect = [];
                text.__boundRect[pageIndex] = [];

                text.__texts = [];
                text.__texts[pageIndex] = [];

                text.__boundRect[pageIndex][index] = { ...measureRect };
                text.__texts[pageIndex][index] = innerText;
            }else{
                if(!text.__boundRect){
                    text.__boundRect = [];
                    text.__texts = [];
                }

                if(!text.__boundRect[pageIndex]){
                    text.__boundRect[pageIndex] = [];
                    text.__texts[pageIndex] = [];
                }

                if(!text.__boundRect[pageIndex][index]){
                    text.__texts[pageIndex][index] = innerText;
                    text.__boundRect[pageIndex][index] = { ...measureRect };
                }else{
                    if(innerText.length > 0){
                        text.__texts[pageIndex][index] = innerText;
                        text.__boundRect[pageIndex][index] = { ...measureRect };
                    }
                }
            }

            if(!option || !option.notAddLayout){
                let result = page.getLastRow(type).addElement(text);
                //text并未加入到当前行(空文本、不可见等元素)
                if(!result){
                    delete text.__boundRect;
                }
            }
        }

        //空行删除
        if(page.getLastRow(type).isEmpty()){
            page.getLastRow(type).removeParagraphOnlyRelFor(text);
            page.removeLastRow(type);
        }

        return newpage;
    }

    /**
     * 如果是不可见元素则直接放入行内，不做任何处理
     * @param {*} element 
     * @param {*} type
     * @returns
     */
    var ifHiddenThenAdd = function(element, type){
        if(isInvisibleElement(element)){
            page.getLastRow(type).addElement(element);
            return true;
        }

        return false;
    }

    /**
     * 根据元素所在段落重新设置父级包围盒
     * @param {*} type 
     * @param {*} element 
     * @param {*} parentRect
     */
    var setParentRectByParagraph = function(type, element, parentRect){
        let pStyle = page.getLastRow(type).getParagraphStyle(element);

        if(pStyle.leftWholeIndent || pStyle.rightWholeIndent){
            let rect = {...parentRect};

            rect.left += pStyle.leftWholeIndent;
            rect.width += pStyle.rightWholeIndent;

            return rect;
        }

        return parentRect;
    }

    /**
     * 判断是否是不可见元素
     * @param {*} element 
     */
    var isInvisibleElement = function (element) {
        return (element.style &&
            element.style.display == "none") || 
            (element.delete && 
            !setting.traceDisplay);
    }

    /**
     * 返回文本元素的内容
     * @param {*} text 
     * @returns 
     */
    var getTextElementContent = function(text){
        if(text.__remainText != null){
            return text.__remainText;
        }else if(text.innerText != null && 
            (text.innerText.length > 0 || typeof(text.innerText) == "number")){
            return text.innerText;
        }else if(text.placeholder != null && text.placeholder.length > 0){
            return text.placeholder;
        }
        return text.innerText;
    }

    /**
     * 对挂载元素进行重新排版
     * @param {*} elements 
     * @param {*} render
     * @param {*} type
     */
    var reformatAttachElement = function(elements, render, type){
        var element = null;

        for(var i = 0; i < elements.length; i++){
            element = elements[i];
            reflow(element, page.getBoundRect(type, true), render, type);
            delete element.__remainText;
        }
    }

    /**
     * 删除挂载元素当前行号之后的包围盒
     * @param {*} elements 
     * @param {*} type
     */
    var deleteBoundAttachElement = function(elements, type){
        var element = null;
        var len = null;
        
        for(var i = 0; i < elements.length; i++){
            element = elements[i];

            len = getTextLessIndexLength(element, page.getIndex(), page.getLastRow(type, true).getIndex());
            if(len > 0){
                element.__remainText = getRemainText(element, len);
            }

            deleteBoundRectGreatIndex(elements[i], page.getIndex(), page.getLastRow(type, true).getIndex());
        }
    }

    /**
     * 从指定位置截取剩余文本长度
     * @param {*} element 
     * @param {*} startIndex 
     */
    var getRemainText = function(element, startIndex){
        var remainText = "";

        if(element.innerText == "" || element.innerText == null){
            if(element.placeholder){
                remainText = element.placeholder.substr(startIndex);
            }
        }else{
            remainText = element.innerText.substr(startIndex);
        }

        return remainText;
    }

    /**
     * 处理长文本的横向排版
     * @param {*} text 
     * @param {*} boundRect 
     * @param {*} parentRect
     * @param {*} type 页面布局类型：body(页体,默认) head(页眉) foot(页脚) 
     * @param {*} option 可选项
     */
    var procWidthFormat = function(text, boundRect, parentRect, type, option){
        var innerText = getTextElementContent(text);
        var textMetrics = painter.measureCurText(innerText, text);
        var splitNum = Math.ceil(textMetrics.width / page.getBoundRect(type).width);

        var pageRect = {...page.getBoundRect(type, true)};
        pageRect.width = parentRect.width;

        var textList = splitText.call(
            this, 
            innerText, 
            boundRect, 
            parentRect,
            pageRect,
            splitNum,
            text
        );

        text.__end = 0;
        
        return procSplitText.call(this, text, textList, type, option);
    }

    /**
     * 处理被拆分的文本
     * @param {*} text 文本元素
     * @param {*} textList 拆分的文本集合
     * @param {*} type 页面布局类型：body(页体,默认) head(页眉) foot(页脚) 
     * @returns 
     */
    var procSplitText = function(text, textList, type, option){
        var index = 0;

        for(var i = 0; i < textList.length; i++){
            var t = textList[i];
            var __boundRect = {
                left: t.startPos.left,
                top: t.startPos.top,
                width: t.textMetrics.width,
                height: t.textMetrics[FONT_ASCENT] + t.textMetrics[FONT_DESCENT],
                textMetrics: t.textMetrics,
                FONT_ASCENT: FONT_ASCENT,
                FONT_DESCENT: FONT_DESCENT,
                textIndent: t.startPos.textIndent
            };

            if(textList[0].startPos.mutationHeight){
                __boundRect.mutationHeight = textList[0].startPos.mutationHeight;
            }
        
            var exceed = isExceed.call(this, __boundRect, text, type);
            if(exceed == -1){
                if(text.__end){
                    delete text.__end;
                }
                break;
            }else if(exceed > 1){
                //忽略溢出
                if(option && option.ignoreExceed){
                    if(text.__boundRect && (!option || !option.notAddLayout)){
                        page.getLastRow(type).addElement(text);
                        break;
                    }
                }else{
                    //只是高度溢出，则将当前行所有元素带到下一行
                    if(exceed == 2){
                        text.__attachElements = page.getLastRow(type).getElementList();
                        deleteBoundAttachElement(text.__attachElements, type);
                        page.removeLastRow(type);
                        if(text.__end == 0){
                            delete text.__end;
                        }
                    }
                    return 2;
                }
            }
            
            if(i == 0){
                index = page.getLastRow(type).getIndex();
            }else{
                index = page.insertRow(type).getIndex();
            }

            if(!text.__texts){
                text.__texts = [];
                text.__boundRect = [];
            }
    
            if(!text.__texts[pageIndex]){
                text.__texts[pageIndex] = [];
                text.__boundRect[pageIndex] = [];
            }

            if(text.__boundRect[pageIndex][index]){
                text.__texts[pageIndex][index] += t.text;
                text.__boundRect[pageIndex][index].width += __boundRect.width;
            }else{
                text.__texts[pageIndex][index] = t.text;
                text.__boundRect[pageIndex][index] = {...__boundRect};

                if(!option || !option.notAddLayout){
                    page.getLastRow(type).addElement(text);
                }
            }

            text.__end += t.text.length;
        }

        var innerText = getTextElementContent(text);

        if(text.__end == innerText.length){
            delete text.__end;
        }

        return 0;
    }

    /**
     * 将文本按合适的长度进行拆分并放入数组
     * @param {*} textContent sText文本内容
     * @param {*} startPos 起始的坐标
     * @param {*} breakPos 折行后的起始坐标
     * @param {*} maxSize 允许的最大宽度和允许的最大高度 {width:0,height:0}
     * @param {*} splitNum 拆分比率
     * @param {*} element 文本元素
     */
    var splitText = function (textContent, startPos, breakPos, maxSize, splitNum, element) {
        var n = {
            textContent: textContent, 
            startPos: startPos, 
            breakPos: breakPos, 
            splitNum: splitNum, 
            textList: []
        };

        var length = null;
        var text = null;
        var _text = null;

        var shiftWidth = null;
        var textMetrics = null;
        var width = null;

        var maxWidth = maxSize.width;
        var keepOn = true;

        while(true){
            length = Math.ceil(n.textContent.length / n.splitNum);
            text = n.textContent.substr(0, length);
    
            textMetrics = painter.measureCurText(text, element);
            shiftWidth = n.startPos.left - maxSize.left;
            width = shiftWidth + textMetrics.width;
    
            if (width > maxWidth && text.length > 1) {
                n.splitNum++;
                continue;
            } else if (width <= maxWidth || text.length == 1) {
                if(n.splitNum == 1 || (length == 1 && length == n.textContent.length)){
                    n.textList.push({
                        startPos: {
                            ...n.startPos
                        },
                        text: text,
                        textMetrics: textMetrics
                    })
                    return n.textList;
                }
    
                _text = null;
                keepOn = false;

                for (var i = length + 1; i <= n.textContent.length; i++) {
                    _text = n.textContent.substr(0, i);
                    textMetrics = painter.measureCurText(_text, element);
    
                    if (shiftWidth + textMetrics.width > maxWidth) {
                        _text = n.textContent.substr(0, i - 1);
                        textMetrics = painter.measureCurText(_text, element);
    
                        var metrics = {};
                        var textItem = {
                            startPos: { ...n.startPos },
                            text: _text,
                            textMetrics: metrics
                        };

                        n.textList.push(textItem);
    
                        if(_text){
                            metrics[FONT_ASCENT] = textMetrics[FONT_ASCENT];
                            metrics[FONT_DESCENT] = textMetrics[FONT_DESCENT];
                            metrics.width = textMetrics.width;
                        }else{
                            //空文本高度设置为0
                            metrics[FONT_ASCENT] = 0;
                            metrics[FONT_DESCENT] = 0;
                            metrics.width = 0;
                            textItem.startPos.top = 0;
                        }
    
                        n.startPos = {
                            top: n.startPos.top + 
                                 (startPos.mutationHeight 
                                    ? startPos.mutationHeight
                                    : ( metrics[FONT_ASCENT] + 
                                        metrics[FONT_DESCENT] )),
                            left: n.breakPos.left
                        };
                        n.breakPos = n.startPos;
                        n.textContent = n.textContent.substr(i - 1);

                        textMetrics = painter.measureCurText(n.textContent, element);
                        shiftWidth = n.startPos.left - maxSize.left;

                        n.splitNum = Math.ceil((shiftWidth + textMetrics.width) / maxWidth);
                        n.splitNum = n.splitNum <= 0 ? 1 : n.splitNum;

                        keepOn = true;

                        break;
                    }
                }

                if(!keepOn){
                    break;
                }
            }
        }

        return n.textList;
    }

    /**
     * 高度溢出或宽度溢出
     * @param {*} boundRect 元素的包围盒
     * @param {*} element 判断的元素
     * @param {*} type 页面布局类型：body(页体,默认) head(页眉) foot(页脚) 
     * 
     * @returns -1忽略  0 不溢出  1 宽度溢出  2 高度溢出  3 宽和高都溢出
     */
    var isExceed = function(boundRect, element, type){
        var page = this.getPage();

        var lastRow = page.getLastRow(type);
        var areaRect = page.getBoundRect(type, true, {autoExtend: true});

        var rowRect = lastRow.getBoundRect();
        var rect = lastRow.measureText(boundRect, element);

        var isWidthExceed = rect.left + rect.width > areaRect.left + areaRect.width;
        var isHeightExceed = false;

        var exceedHeight = 0;

        if(type == "body"){
            if(isWidthExceed){
                exceedHeight = rowRect.top + rowRect.height + rect.occupyHeight - (areaRect.top + areaRect.height);
                isHeightExceed = exceedHeight > 0;
            }else{
                if(element._sType == "sText"){
                    isHeightExceed = rect.top + rect.textMetrics[FONT_DESCENT] > areaRect.top + areaRect.height;
                }else{
                    exceedHeight = rect.top + rect.height - (areaRect.top + areaRect.height);
                    isHeightExceed = exceedHeight > 0;
                }
            }
        }else if(type == "head" || type == "foot"){
            // var areaActualRect = page.getBoundRect(type);

            // if(isWidthExceed){
            //     exceedHeight = areaActualRect.height + rect.occupyHeight - areaRect.height
            //     isHeightExceed = exceedHeight > 0;
            // }else{
                //exceedHeight = areaActualRect.height + (rect.occupyHeight - rowRect.height) - areaRect.height;
                //isHeightExceed = exceedHeight > 0;
            // }
            //页眉页脚高度不限制
            isHeightExceed = false;
        }
        
        return (isWidthExceed ? 1 : 0) + (isHeightExceed ? 2 : 0);
    }

    /**
     * 上下标变异
     */
    var supOrSubAlignMutation = function(text){
        var metrics = null;
        if(text.style.sup || 
           text.style.sub){
            metrics = painter.measureCurText(text);

            //编辑后局部排版
            if(text.__boundRect){
                var r = text.__boundRect[text.__boundRect.length - 1];
                r = r[r.length - 1];
                if(r.mutationHeight){
                    metrics.mutationHeight = r.mutationHeight;
                }
            }
        }
        return metrics;
    }

    /**
     * 如果需要就插入新行
     * @param {*} element 
     * @param {*} type 
     */
    var insertRowIfNeed = function(element, type){
        var page = this.getPage();

        //当前行已经以段落元素结尾
        if(page.getLastRow(type).isEndWithParagraph()){
            page.insertRow(type);
            return true;
        }
        //当前行已经以换行符结尾
        else if(page.getLastRow(type).isEndWithBreakline()){
            page.insertRow(type);
            return true;
        }else if(element.style.display == "block"){
            //当前元素是块状元素，且当前行存在可见元素
            if(page.getLastRow(type).hasVisibleElement()){
                page.insertRow(type);
                return true;
            }
        }else {
            //当前元素的前一个元素是块状元素
            var lastRow = page.getLastRow(type);
            var lastElement = lastRow.getLastVisibleElement();
            if(lastElement){
                if(lastElement.style.display == "block"){
                    page.insertRow(type);
                    return true;
                }
            }
        }

        return false;
    }

    /**
     * 判断元素是否满足删除条件
     * @param {*} element 元素
     * @param {*} row 所在行
     * @param {*} pageIndex 页码
     * @param {*} type 区域类型
     * @returns 
     */
    var canDeleteElement = function(element, row, pageIndex, type){
        if(element._sType == "sText"){
            var elementIndex = row.indexOf(element);
            if(elementIndex < 0) return false;

            if(element.delete && setting.leaveTrace){
                return false;
            }

            //元素当前行内容不为空
            var flg = element.__texts &&
                element.__texts[pageIndex] &&
                element.__texts[pageIndex][row.getIndex()];

            //最后一个元素
            var isFirst = pageIndex == 1 && 
                row.getIndex() == 1 && 
                elementIndex == 0;

            flg = flg || isFirst;

            //若为空
            if(!flg) {
                return true;
            }
            
            //内容为空且不是第一个元素
            flg = !element.innerText && !isFirst;

            //本行第一个元素
            var isRowFirst = row.getFirstVisualElement(element._sType) == element;

            //删到当前行最后一个文本元素，元素内容为空，且上一行末尾不是回车，则可以删除元素
            if(isRowFirst && row.getIndex() > 1){
                var prevRow = row.getPage().getRow(type, row.getIndex() - 2);
                flg = flg && 
                    !prevRow.isEndWithParagraph() && !prevRow.isEndWithBreakline();
            }

            if(flg) return true;
        }else if(element._sType == "sParagraph"){
            return !element.__boundRect;
        }

        return false;
    }

    /**
     * 对删除动作的预处理
     * @param {*} element 当前变异的元素集合
     * @param {*} offset 元素偏移量
     * @param {*} type 页面布局类型：body(页体,默认) head(页眉) foot(页脚) 
     * @param {*} pageList 分页集合
     * @param {*} opt 可选项
     */
    var preProcessForDelete = function(elements, offset, type, pageList, opt){
        if(offset.minPageIndex == null){
            offset.minPageIndex = 0;
        }

        if(offset.minRowIndex == null){
            offset.minRowIndex = 0;
        }

        var startPageIndex = offset.pageIndex;
        var startRowIndex = offset.rowIndex;

        var pages = pageList;

        var el = null; 
        var eleOffset = null;
        var row = null;
        var tableCount = 0;

        for(var i in elements){
            el = elements[i];

            if(el.element._sType == "sTableRow" || 
                el.element._sType == "sTableColumn"){
                continue;
            }

            eleOffset = el.offset;

            if(eleOffset.next) {
                if(el.element._sType != "sTable"){
                    tableCount++;
                    continue;
                }
            }

            if(el.mutate){
                row = pages.getPage(eleOffset.pageIndex).getRow(type, eleOffset.rowIndex - 1);

                if(canDeleteElement(el.element, row, eleOffset.pageIndex, type)){
                    var index = row.getElementList().indexOf(el.element);
                    if(index > -1){
                        row.getElementList().splice(index, 1);
                    }
                    deleteBoundRectGreatIndex(el.element, eleOffset.pageIndex, row.getIndex());
                }

                if(!startPageIndex || startPageIndex >= eleOffset.pageIndex){
                    startPageIndex = eleOffset.pageIndex;

                    if(!startRowIndex || startRowIndex > row.getIndex()){
                        startRowIndex = row.getIndex();
                    }
                }
            }else if(el.delete){
                let dr = el.delRange;
                let sRowIndex = null;
                let eRowIndex = null;
                let pg = null;

                for(var i = dr.startPageIndex; i <= dr.endPageIndex; i++){
                    pg = pages.getPage(i);

                    if(i == dr.startPageIndex){
                        sRowIndex = dr.startRowIndex;
                        if(i == dr.endPageIndex){
                            eRowIndex = dr.endRowIndex;
                        }else{
                            eRowIndex = pg.getLastRow(type, true).getIndex();
                        }
                    }else if(i == dr.endPageIndex){
                        sRowIndex = 1;
                        eRowIndex = dr.endRowIndex;
                    }else{
                        sRowIndex = 1;
                        eRowIndex = pg.getLastRow(type, true).getIndex();
                    }

                    var index = null;
                    for(var j = sRowIndex; j <= eRowIndex; j++){
                        row = pg.getRow(type, j - 1);

                        index = row.getElementList().indexOf(el.element);
                        if(index > -1) {
                            row.getElementList().splice(index, 1);
                        }

                        deleteBoundRectGreatIndex(el.element, i, j);
                    }
                }

                if(!startPageIndex || startPageIndex >= dr.startPageIndex){
                    startPageIndex = dr.startPageIndex;

                    if(!startRowIndex || startRowIndex > sRowIndex){
                        startRowIndex = sRowIndex;
                    }
                }
            }else if(el.mutateNew){
                row = pages.getPage(eleOffset.pageIndex).getRow(type, eleOffset.rowIndex - 1);
                row.getElementList().splice(eleOffset.elementIndex, 0, el.element);
            }

            if(offset.minPageIndex < eleOffset.pageIndex){
                offset.minPageIndex = eleOffset.pageIndex;

                if(offset.minRowIndex < eleOffset.rowIndex){
                    offset.minRowIndex = eleOffset.rowIndex;
                }
            }
        }

        //删除到一页的第一行，则将起始偏移量调整到上一页
        if(!offset.next && offset.rowIndex == 1 && startPageIndex > 1){
            if(pages.contain(startPageIndex - 1)){
                startPageIndex -= 1;
                startRowIndex = pages
                    .getPage(startPageIndex).getLastRow(type, true).getIndex();
            }
        }

        var result = {
            startPageIndex: startPageIndex,
            startRowIndex: startRowIndex,
            needExpansion: true
        };

        if(tableCount > 0 && tableCount == elements.length){
            result = preProcessForTable.call(this, elements, offset, type, pageList, ssDict.sActionType.DELETE, opt);
        }

        if(!result.startPageIndex || result.startPageIndex > startPageIndex){
            result.startPageIndex = startPageIndex;

            if(!result.startRowIndex || result.startRowIndex > startRowIndex){
                result.startRowIndex = startRowIndex;
            }
        }

        return result;
    }

    /**
     * 对插入动作的预处理
     * @param {*} element 当前变异的元素集合
     * @param {*} offset 元素偏移量
     * @param {*} type 页面布局类型：body(页体,默认) head(页眉) foot(页脚) 
     * @param {*} pageList 分页集合
     * @param {*} opt 可选项
     */
    var preProcessForInsert = function(elements, offset, type, pageList, opt){
        opt = opt ? opt : {};

        var row = null;
        var result = {
            startPageIndex: offset.pageIndex,
            startRowIndex: offset.rowIndex,
            needExpansion: true
        }

        if(offset.next){
            result = preProcessForTable.call(this, elements, offset, type, pageList, ssDict.sActionType.INSERT, opt);

            if(!result.startPageIndex || result.startPageIndex > offset.pageIndex){
                result.startPageIndex = offset.pageIndex;

                if(!result.startRowIndex || result.startRowIndex < offset.rowIndex){
                    result.startRowIndex = offset.rowIndex;
                }
            }
        } else {
            row = pageList.getPage(offset.pageIndex).getRow(type, offset.rowIndex - 1);

            var elems = [];

            for(var i in elements){
                elems.push(elements[i].element);
            }

            if(opt.notDeleteFirst){
                row.getElementList().splice(offset.elementIndex, 0, ...elems);
            }else{
                row.getElementList().splice(offset.elementIndex, 1, ...elems);
            }
        }

        return result;
    }

    /**
     * 对修改动作的预处理
     * @param {*} element 当前变异的元素集合
     * @param {*} offset 元素偏移量
     * @param {*} type 页面布局类型：body(页体,默认) head(页眉) foot(页脚) 
     * @param {*} pageList 分页集合
     * @param {*} opt 可选项
     */
    var preProcessForModify = function(elements, offset, type, pageList, opt){
        if(elements.length == 0) return;

        if(offset.minPageIndex == null){
            offset.minPageIndex = 0;
        }

        if(offset.minRowIndex == null){
            offset.minRowIndex = 0;
        }

        var result = {
            startPageIndex: offset.startPageIndex ? offset.startPageIndex : offset.pageIndex,
            startRowIndex: offset.startRowIndex ? offset.startRowIndex : offset.rowIndex,
            needExpansion: true
        };

        var pages = pageList;

        var el = null;
        var eleOffset = null;
        var row = null;
        var index = null;
        var cells = [];

        for(var i in elements){
            el = elements[i];

            eleOffset = el.offset;
            
            if(!eleOffset) continue;

            if(el.offset.next && (
                el.element._sType == "sText" ||
                el.element._sType == "sLayer")) {
                cells.push(el);
                continue;
            }else if(el.element._sType == "sParagraph") {
                el.element.__mutate = true;
                continue;
            }else if(el.element._sType == "sTableCell") {
                el.element.__mutate = true;
                continue;
            }else if(el.element._sType == "sTableRow" ||
                el.element._sType == "sTableColumn"){
                el.element.__mutate = true;

                var si = getStartIndexFromTable(el.table);
                if(result.startPageIndex > si.startPageIndex){
                    result.startPageIndex = si.startPageIndex;
                    result.startRowIndex = si.startRowIndex;
                }

                continue;
            }

            if(el.mutate){
                row = pages.getPage(eleOffset.pageIndex).getRow(type, eleOffset.rowIndex - 1);
                if(!row) continue;
                index = row.getElementList().indexOf(el.element);
            }else if(el.mutateNew){
                row = pages.getPage(eleOffset.pageIndex).getRow(type, eleOffset.rowIndex - 1);
                row.getElementList().splice(eleOffset.elementIndex, 0, el.element);
            }else{
                row.getElementList().splice(++index, 0, el.element);
            }

            if(result.startPageIndex >= eleOffset.pageIndex){
                result.startPageIndex = eleOffset.pageIndex;

                if(result.startRowIndex > row.getIndex()){
                    result.startRowIndex = row.getIndex();
                }
            }
            
            if(offset.minPageIndex < row.getPageIndex()){
                offset.minPageIndex = row.getPageIndex();
            }
            
            if(offset.minRowIndex < row.getIndex()){
                offset.minRowIndex = row.getIndex();
            }
        }

        if(cells.length > 0){
            var preResult = preProcessForTable.call(this, cells, offset, type, pageList, ssDict.sActionType.MODIFY, opt);
            if(cells.length == elements.length){
                result = preResult;
            }else{
                result = {...preResult, needExpansion: true};
            }
        }

        if(!result.startPageIndex || result.startPageIndex > offset.pageIndex){
            result.startPageIndex = offset.pageIndex;

            if(!result.startRowIndex || result.startRowIndex > offset.rowIndex){
                result.startRowIndex = offset.rowIndex;
            }
        }

        return result;
    }

    /**
     * 对替换动作的预处理
     * @param {*} element 当前变异的元素集合
     * @param {*} offset 元素偏移量
     * @param {*} type 页面布局类型：body(页体,默认) head(页眉) foot(页脚) 
     * @param {*} pageList 分页集合
     * @param {*} opt 可选项
     */
    var preProcessForReplace = function(elements, offset, type, pageList, opt){
        if(elements.length == 0) return;

        if(offset.minPageIndex == null){
            offset.minPageIndex = 0;
        }

        if(offset.minRowIndex == null){
            offset.minRowIndex = 0;
        }

        opt = opt ? opt : {};

        var result = {
            startPageIndex: offset.startPageIndex ? offset.startPageIndex : offset.pageIndex,
            startRowIndex: offset.startRowIndex ? offset.startRowIndex : offset.rowIndex,
            needExpansion: true
        };

        var pages = pageList;

        var el = null;
        var eleOffset = null;
        var row = null;
        var cells = [];
        var index = 0;

        for(var i in elements){
            el = elements[i];

            eleOffset = el.offset;

            if(el.offset.next && (
                el.element._sType == "sText" ||
                el.element._sType == "sLayer")) {
                cells.push(el);
                continue;
            }else if(el.element._sType == "sParagraph") {
                el.element.__mutate = true;
                continue;
            }else if(el.element._sType == "sTableCell") {
                el.element.__mutate = true;
                continue;
            }else if(el.element._sType == "sTableRow" ||
                el.element._sType == "sTableColumn"){
                el.element.__mutate = true;

                var si = getStartIndexFromTable(el.table);
                if(result.startPageIndex > si.startPageIndex){
                    result.startPageIndex = si.startPageIndex;
                    result.startRowIndex = si.startRowIndex;
                }

                continue;
            }

            row = pages.getPage(eleOffset.pageIndex).getRow(type, eleOffset.rowIndex - 1);

            if(el.mutate){
                //纯替换
                opt.actType = ssDict.sActionType.REPLACE;
                index = row.getElementList().indexOf(el.element);
            }else if(el.mutateNew){
                opt.actType = null;
                row.getElementList().splice(eleOffset.elementIndex, 0, el.element);
            }else if(el.delete){
                opt.actType = null;
                let ind = row.getElementList().indexOf(el.element);
                if(ind > -1){
                    row.getElementList().splice(ind, 1);
                }
            }else{
                row.getElementList().splice(++index, 0, el.element);
            }
            
            if(offset.minPageIndex < row.getPageIndex()){
                offset.minPageIndex = row.getPageIndex();
            }
            
            if(offset.minRowIndex < row.getIndex()){
                offset.minRowIndex = row.getIndex();
            }
        }

        if(cells.length > 0){
            var preResult = preProcessForTable.call(
                this, cells, offset, type, pageList, ssDict.sActionType.REPLACE, opt);

            if(cells.length == elements.length){
                result = preResult;
            }else{
                result = {...preResult, needExpansion: true};
            }
        }

        if(!result.startPageIndex || result.startPageIndex > offset.pageIndex){
            result.startPageIndex = offset.pageIndex;

            if(!result.startRowIndex || result.startRowIndex > offset.rowIndex){
                result.startRowIndex = offset.rowIndex;
            }
        }

        return result;
    }

    /**
     * 对表格重排版的预处理
     * @param {*} elements 当前变异的元素集合
     * @param {*} offset 偏移量
     * @param {*} type 页面布局类型：body(页体,默认) head(页眉) foot(页脚) 
     * @param {*} pageList 分页集合
     * @param {*} actType 动作类型
     * @param {*} opt 可选项
     */
    var preProcessForTable = function(elements, offset, type, pageList, actType, opt){
        opt = opt ? opt : {};

        var el = null;
        var ele = null;
        var els = [];
        var cells = [];

        var ind = -1;
        var offset = null;
        var result = null;

        for(var i in elements){
            el = elements[i];

            ele = {
                element: el.element,
                offset: null
            };

            if(el.mutate !== undefined){
                ele.mutate = el.mutate;
            }

            if(el.mutateNew !== undefined){
                ele.mutateNew = el.mutateNew;
            }

            if(el.delete !== undefined){
                ele.delete = el.delete;
            }

            if(el.delRange !== undefined){
                ele.delRange = el.delRange;
            }

            if(el.main !== undefined){
                ele.main = el.main;
                ele.offset = el.offset;
            }

            if(!el.offset || !el.offset.next) {
                els[ind].elements.push(ele);
                continue;
            }

            offset = ost.extractOffset(el.offset, true);

            if(el.offset.range){
                offset.range = el.offset.range;
            }

            result = pageList.lookup(type, ost.extractCellOffset(el.offset));

            ind = cells.indexOf(result.ref);

            if(ind < 0){
                cells.push(result.ref);
                ind = cells.length - 1;
                if(!els[ind]){
                    els[ind] = {
                        elements: [],
                        offset: offset,
                        _offset: el.offset,
                        tables: result.tables
                    };
                }
            }

            ele.offset = offset;

            els[ind].elements.push(ele);
        }

        var needExpansion = false;
        var pageHeight = 0;

        let cell = null;
        for(var j in cells){
            cell = cells[j];
            if(!cell.__pageList) continue;

            pageHeight = getPageHeight(cell.__pageList);
            result = this.reformat(
                els[j].elements, 
                els[j].offset, 
                "body", 
                cell.__pageList, 
                actType, 
                opt
            );

            // cell.__pageList.setMutate(true);
            cell.__contentMutate = true;
            cell.children = extractElementsFromPage(cell.__pageList, "body");
            
            setCellAlign(cell);
            
            if(isRectNeedChange(cell.__pageList, els[j].offset, cell, els[j].tables[0], pageHeight)){
                needExpansion = true;
            }

            if(cell.__mutate){
                needExpansion = true;
            }

            //对跨页单元格内部操作时(跨页删除)，有时会重绘不到相应页面
            if(!needExpansion && result.pageRange && cell.__boundRect.length > 1){
                for(var i in cell.__boundRect){
                    i = parseInt(i);
                    if(isNaN(i)) continue;
                    if(result.pageRange.indexOf(i) < 0){
                        result.pageRange.push(i);
                    }
                }
            }
        }

        el = els[0];

        if(opt.actType != ssDict.sActionType.REPLACE){
            if(!needExpansion){
                offset = el._offset;
                ost.mergeOffsetNext(offset, ost.extractShallowOffset(result));
    
                var lookResult = pageList.lookup(type, offset);
                var computeResult = computeElementOffset.call(this, lookResult.row, lookResult.ref, 
                    lookResult.contentIndex, lookResult.contentIndex + 1);
    
                if(computeResult.left != null){
                    result.left = lookResult.boundRect.left + computeResult.left - computeResult.boundRect.left;
                }else{
                    result.left = lookResult.boundRect.left;
                }
                
                result.top = lookResult.boundRect.top;
    
                if(!result.offset){ 
                    result.offset = offset;
                }
            }else{
                var tableResult = getStartIndexFromTable(el.tables[0]);
                result.startPageIndex = tableResult.startPageIndex;
                result.startRowIndex = tableResult.startRowIndex;
            }
        }

        result.needExpansion = needExpansion;

        return result;
    }

    /**
     * 获取表格的起始页和起始行
     * @param {*} table 
     * @returns 
     */
    var getStartIndexFromTable = function(table){
        var result = {};
        var boundRect = table.__boundRect;

        for(var i in boundRect){
            result.startPageIndex = parseInt(i);
            for(var j in boundRect[i]){
                result.startRowIndex = parseInt(j);
                break;
            }
            break;
        }

        return result;
    }

    /**
     * 从分页集合对象中抽取所有元素
     * @param {*} pages 
     * @param {*} type
     */
    var extractElementsFromPage = function(pages, type){
        var startPageIndex = pages.getFirstPage().getIndex();
        var endPageIndex = pages.getLastPage().getIndex();

        var startRowIndex = 0;
        var endRowIndex = 0;

        var page = null;
        var row = null;
        var elements = null;
        var children = [];

        for(var i = startPageIndex; i <= endPageIndex; i++){
            page = pages.getPage(i);

            if(page.getRowCount(type) == 0) continue;

            startRowIndex = page.getFirstRow(type).getIndex();
            endRowIndex = page.getLastRow(type).getIndex();

            for(var j = startRowIndex; j <= endRowIndex; j++){
                row = page.getRow(type, j - 1);
                elements = row.getElementList();
                
                for(var k in elements){
                    if(children.indexOf(elements[k]) > -1) continue;
                    children.push(elements[k]);
                }
            }
        }

        return children;
    }

    /**
     * 附加性能优化相关参数
     * @param {*} opt1 
     * @param {*} opt2 
     */
    var attachPerformanceOptimization = function(opt1, opt2){
        if(!opt2) return;

        if(!opt1.performanceOptz){
            opt1.performanceOptz = {};
        }
        
        opt1.performanceOptz.cellContentEdit = opt2.cellContentEdit;
        opt1.performanceOptz.contentMove = opt2.contentMove;

        if(opt1 === opt2){
            delete opt2.cellContentEdit;
            delete opt2.contentMove;
        }
    }

    /**
     * 内容重排
     * @param {*} elements 当前变异的元素集合
     * @param {*} offset 元素偏移量
     * @param {*} type 页面布局类型：body(页体,默认) head(页眉) foot(页脚) 
     * @param {*} pageList 分页集合
     * @param {*} actType 含义参照 ssDict.sActionType
     * @param {*} opt 可选项
     */
    this.reformat = function(elements, offset, type, pageList, actType, opt) {
        var result = null;

        //删除操作
        if(actType == ssDict.sActionType.DELETE){
            result = preProcessForDelete.call(this, elements, offset, type, pageList, opt);
        }
        //插入操作
        else if(actType == ssDict.sActionType.INSERT){
            result = preProcessForInsert.call(this, elements, offset, type, pageList, opt);
        }
        //修改操作
        else if(actType == ssDict.sActionType.MODIFY){
            result = preProcessForModify.call(this, elements, offset, type, pageList, opt);
        }
        //替换操作
        else if(actType == ssDict.sActionType.REPLACE){
            result = preProcessForReplace.call(this, elements, offset, type, pageList, opt);
        }

        //needExpansion:需要扩展(表明内容变化超出现有范围)
        if(!result.needExpansion){
            return result;
        }else if(!opt || !opt.circleReformat){
            //对嵌套表格从内到外循环排版
            let arr = ost.splitOffset(offset);
            if(arr.length > 2){
                let res = result;

                opt = {
                    circleReformat: true
                };
                let curIndex = arr.length - 1;

                // for(let ind = curIndex; ind > 0; ind -= 2){
                    let table = arr[curIndex].table;
                    let concatOffset = ost.concatOffset(arr, 0, curIndex - 1);
    
                    result = this.reformat([{
                        element: table,
                        mutate: true,
                        offset: getElementOffset(table)
                    }], concatOffset, type, pageList, actType, opt);

                    // if(!result.needExpansion) break;
                // }

                if(res.ref){
                    rectifyRowByAbsoluteIndex(res.ref, res);

                    let locateOffset = this.locateElementOffset(res, res.ref);
                    res.left = locateOffset.left;
                    res.top = locateOffset.top;
                }

                filterPaintPageRange(res.pageRange, result.pageRange);
                
                return res;
            }
        }

        var needExpansion = result.needExpansion;

        attachPerformanceOptimization(result, opt);

        var fr = reformatByOffset.call(this, offset, type, pageList, result);

        //插入操作
        if(actType == ssDict.sActionType.INSERT){
            result = afterProcessForInsert(elements, offset);
        }
        //删除操作
        else if(actType == ssDict.sActionType.DELETE){
            result = afterProcessForDelete(elements, offset, fr.tempPageList, type);
        }
        //修改操作
        else if(actType == ssDict.sActionType.MODIFY){
            result = afterProcessForModify(elements, offset);
        }
        //替换操作
        else if(actType == ssDict.sActionType.REPLACE){
            result = afterProcessForReplace(elements, offset);
        }

        var pageRange = result && result.pageChangeRange;

        var result = rewritePage.call(
            this, 
            result ? result.element : null,
            result ? result.offset : null, 
            fr.rowOffset, 
            fr.areas, 
            pageList, 
            fr.tempPageList, 
            actType
        );

        result = result ? result : {};
        result.needExpansion = needExpansion;

        filterPaintPageRange(result.pageRange, pageRange, offset, opt);

        return result;
    }

    /**
     * 筛选最优重绘页面
     * @param {*} returnRange 
     * @param {*} changeRange 
     * @param {*} offset
     * @param {*} opt 
     */
    var filterPaintPageRange = function(returnRange, changeRange, offset, opt){
        if(returnRange){
            if(changeRange){
                for(let i in changeRange){
                    if(returnRange.indexOf(changeRange[i]) > -1) continue;
                    returnRange.push(changeRange[i]);
                }
            }
            
            if(offset && returnRange.indexOf(offset.pageIndex) < 0){
                returnRange.push(offset.pageIndex);
            }

            //单元格编辑
            if(opt && opt.cellContentEdit && offset.next){
                for(let j = 0; j < returnRange.length; j++){
                    if(returnRange[j] < opt.cellContentEdit.startPageIndex){
                        returnRange.splice(j, 1);
                        j--;
                    }
                }
            }
        }
    }

    /**
     * 根据偏移量重新排版
     * @param {*} offset 重新排版的起始偏移量
     * @param {*} type 页面布局类型：body(页体,默认) head(页眉) foot(页脚) 
     * @param {*} pageList 分页集合
     * @param {*} option 可选项
     */
    var reformatByOffset = function(offset, type, pageList, opt){
        opt = opt ? opt : {};

        var startPageIndex = type == "body" ? opt.startPageIndex : 1;
        var startRowIndex = opt.startRowIndex;

        var currentPage = pageList.getPage(startPageIndex);
        var pageRect = currentPage.getBoundRect();
        var tempPageList = new sPageList();

        var areas = null;
        var isRun = {};
        var lastEle = {};
        var option = currentPage.getOption();

        if(type == "body"){
            areas = ["body"];

            option.head = currentPage.getArea("head");
            option.foot = currentPage.getArea("foot");
        }else if(type == "head" || type == "foot"){
            areas = [type, "body"];
            isRun[type] = false;

            var t = type == "head" ? "foot" : "head";
            
            option[t] = currentPage.getArea(t);
            option[type] = null;
        }else{
            areas = ["head", "foot", "body"];
            
            isRun.head = false;
            isRun.foot = false;

            option.head = null;
            option.foot = null;
            option.body = null;
        }

        //创建临时页，用于重新排版
        var tempPage = tempPageList.insertPage({
            ...option, 
            startIndex: startPageIndex
        });

        //创建排版引擎
        var render = new sLayoutEngine(
            painter.createPainter(), 
            tempPage, 
            ratio, {
                pageRect: pageRect,
                setting: setting
            }
        );
        
        var newpage = 0;
        var endPageIndex = -1;
        var endRowIndex = -1;
        var typesetElements = [];
        var skip = false;
        var enter = false;
        var area = null;

        var rowOffset = {
            replaceAll: true,
            startPageIndex: startPageIndex,
            startRowIndex: startRowIndex,
            endPageIndex: endPageIndex,
            endRowIndex: endRowIndex
        };

        var lastRowIndex = 0;
        var resetRowBoundRect = false;
        var paragraphIndex = null;
        var lastPageIndex = pageList.getLastPage().getIndex();
        var rOpt = opt.performanceOptz ? opt.performanceOptz : {};

        //从当前页，一直遍历到相同行为止
        for(var pIndex = startPageIndex; pIndex <= lastPageIndex; pIndex++){
            currentPage = pageList.getPage(pIndex);

            var curEle = null;
            var row = null;
            var len = 0;

            for(var x = 0; x < areas.length; x++){
                area = areas[x];

                if(isRun[area] === false){
                    isRun[area] = true;
                }else if(isRun[area]){
                    continue;
                }

                lastRowIndex = currentPage.getRowCount(area);

                if(type == "head" && area == "body"){
                    startRowIndex = 1;
                }else if(type == "foot" && area == "body"){
                    startRowIndex = 1;

                    if(isFootRectChange(page, tempPage)){
                        offset.minPageIndex = lastPageIndex;
                        offset.minRowIndex = lastRowIndex - 1;
                    }
                }

                for(var i = 0; i < lastRowIndex; i++){ 
                    row = currentPage.getRow(area, i);
    
                    //先将当前页行号小于变异元素所在行行号的行放入临时页
                    if(row.getIndex() < startRowIndex){
                        tempPage.insertRow(area, currentPage.getRow(area, i), true);
                    }else{
                        if(resetRowBoundRect){
                            //表格需要重新排版
                            if(!row.containTable()){
                                //判断该行是否超过临时页边界
                                if(tempPage.isOutBoundOfBody(row)){
                                    tempPage = tempPageList.insertPage(tempPage.getOption());
                                    render.bindPage(tempPage);
                                }
                
                                //计算该行在临时页中和当前页中的位置是否相等
                                if(tempPage.isInsertRowEqual(area, row)){
                                    rowOffset.replaceAll = false;
                                    skip = true;
                                }

                                tempPage.insertRow(area, row, false);
            
                                endPageIndex = tempPage.getIndex();
                                endRowIndex = tempPage.getLastRow(area).getIndex();
                
                                updateRowOffset(rowOffset, 
                                    startPageIndex, startRowIndex, endPageIndex, endRowIndex);

                                if(skip){
                                    break;
                                }

                                continue;
                            }else{
                                rOpt.contentMove = true;
                            }
                        }

                        var elementList = row.getElementList();
    
                        enter = false;
                        paragraphIndex = null;

                        //移除段落引用属性
                        if(elementList.length > 0 && 
                            typesetElements.indexOf(elementList[0]) < 0){
                            for(var m in elementList){
                                if(elementList[m].__paragraphIndex != paragraphIndex){
                                    row.removeParagraphOnlyRelFor(elementList[m], true);
                                    paragraphIndex = elementList[m].__paragraphIndex;
                                }
                            }
                        }
    
                        //对当前行元素重新排版
                        for(var j = 0; j < elementList.length; j++){
                            curEle = elementList[j];

                            rOpt.prevElement = elementList[j - 1];
                            rOpt.nextElement = elementList[j + 1];
                            rOpt.pageIndex = pIndex;
                            rOpt.rowIndex = row.getIndex();
    
                            //阻止相同元素重复排版
                            if(typesetElements.indexOf(curEle) > -1) {
                                continue;
                            }
    
                            typesetElements.push(curEle);
    
                            len = getTextLessIndexLength(curEle, pIndex, row.getIndex());
                            if(len > 0){
                                curEle.__remainText = getRemainText(curEle, len);
                            }
    
                            deleteBoundRectGreatIndex(curEle, pIndex, row.getIndex());

                            //建立双向链接
                            linkElement(lastEle[area], curEle);
                            
                            //在临时页中重新排版
                            newpage = reflow(curEle, 
                                tempPage.getBoundRect(area, true, {autoExtend: true}), render, area, rOpt);

                            if(!this.unlinkElement(curEle)){
                                lastEle[area] = curEle;
                            }

                            delete curEle.__remainText;
    
                            //需新增分页
                            if(newpage > 0){
                                if(area == "body"){
                                    if(curEle.__end){
                                        curEle.__end += len;
                                    }
        
                                    while(newpage > 0){
                                        tempPage = tempPageList.insertPage(tempPage.getOption())
                                        render.bindPage(tempPage);
            
                                        //如果返回1，则对当前元素内容未排版部分继续排版
                                        //如果返回2, 则创建新页后跳出循环（分页符效果）
                                        if(newpage < 9){
                                            newpage = reflow(curEle, 
                                                tempPage.getBoundRect(area, true), render, area, rOpt);
                                        }else{
                                            tempPage.insertRow(area);
                                            break;
                                        }
                                    };
                                }else if(area == "head" || area == "foot"){
                                    continue;
                                }
                            }
    
                            enter = true;
                        }
    
                        if(!enter) continue;
    
                        if(offset.minPageIndex && pIndex < offset.minPageIndex){
                            continue;
                        }
    
                        if(offset.minRowIndex && pIndex == offset.minPageIndex && i + 1 < offset.minRowIndex){
                            continue;
                        }
    
                        //如果排版到段落末尾，则之后行内的元素不再进行排版，
                        //因为只是行的位置变了，其内容并未改变
                        if(area == "body" && row.isEndWithParagraph()){
                            resetRowBoundRect = true;
                            continue;
                        }
                    }
                }
            }

            //达到跳出页码循环条件，必须放在下面代码之前
            if(skip) break;

            //第二次页码循环开始之前必须设置为1
            startRowIndex = 1;

            //设置当前终止页码和终止行
            endPageIndex = tempPage.getIndex();
            endRowIndex = tempPage.getLastRow(area).getIndex();
            
            updateRowOffset(rowOffset, 
                startPageIndex, startRowIndex, endPageIndex, endRowIndex);
        }

        return {
            areas: areas,
            tempPageList: tempPageList,
            rowOffset: rowOffset
        }
    }

    /**
     * 重新排版
     * @param {*} offset 重新排版的起始偏移量
     * @param {*} type 页面布局类型：body(页体,默认) head(页眉) foot(页脚) 
     * @param {*} pageList 分页集合
     * @param {*} option 可选项
     */
    this.reformat2 = function(offset, type, pageList, opt){
        attachPerformanceOptimization(opt, opt);
        var fr = reformatByOffset.call(this, offset, type, pageList, opt);
        var result = rewritePageByTempPage.call(
            this, 
            fr.rowOffset, 
            fr.areas, 
            pageList, 
            fr.tempPageList
        );
        return result;
    }

    /**
     * 判断原始页和临时页的页脚区域的大小是否发生改变
     * @param {*} page 
     * @param {*} tempPage 
     */
    var isFootRectChange = function(page, tempPage){
        var oldFootRect = page.getBoundRect("foot");
        var newFootRect = tempPage.getBoundRect("foot");
        
        return oldFootRect.height != newFootRect.height;
    }

    /**
     * 更新rowOffset
     * @param {*} rowOffset 
     * @param {*} endPageIndex 
     * @param {*} endRowIndex 
     */
    var updateRowOffset = function(rowOffset, 
        startPageIndex, startRowIndex, endPageIndex, endRowIndex){

        if(startPageIndex > 0 && rowOffset.startPageIndex > startPageIndex){
            rowOffset.startPageIndex = startPageIndex;
            rowOffset.startRowIndex = startRowIndex;
        }else if(startRowIndex > 0 && rowOffset.startRowIndex > startRowIndex){
            rowOffset.startRowIndex = startRowIndex;
        }

        if(rowOffset.endPageIndex < endPageIndex){
            rowOffset.endPageIndex = endPageIndex;
            rowOffset.endRowIndex = endRowIndex;
        }else if(rowOffset.endRowIndex < endRowIndex){
            rowOffset.endRowIndex = endRowIndex;
        }
    }

    /**
     * 包围盒高度是否需要变化(单元格等含内部页的元素)
     * @param {*} pageList
     * @param {*} offset
     * @param {*} cell
     * @param {*} table
     * @param {*} oldPageHeight
     */
    var isRectNeedChange = function(pageList, offset, cell, table, oldPageHeight){
        //当前单元格页面高度集合
        var pageHeight = getPageHeight(pageList);

        //当前页面高度未发生变化
        if(pageHeight == oldPageHeight){
            return false;
        }

        //当前单元格包围盒高度集合
        var height = 0;
        for(var i in cell.__boundRect){
            for(var j in cell.__boundRect[i]){
                height += cell.__boundRect[i][j].height;
            }
        }

        if(cell.__boundRect.verticalOffsetHeight){
            //当前单元格页面高度超出单元格包围盒高度
            if(pageHeight + cell.__boundRect.verticalOffsetHeight > height){
                return true;
            } 
        }else{
            //当前单元格页面高度超出单元格包围盒高度
            if(pageHeight > height) {
                return true;
            }
        }

        var rowHeight = null;
        var curRow = table.getRows(offset.tableRowIndex);
        if(curRow.style && curRow.style.height != null){
            rowHeight = curRow.style.height;
        }

        //如果指定了行高
        if(rowHeight){
            //页面的高度在行高以下变化
            if(oldPageHeight <= rowHeight && 
                pageHeight <= rowHeight){
                return false;
            }
        }

        //同一行其他单元格页面高度集合
        var otherCell = null;
        var maxOtherHeight = 0;
        var sumHeight = 0;
        var pHeight = 0;
        
        var endRowIndex = offset.tableRowIndex + cell.rowspan - 1;

        for(var i = offset.tableRowIndex; i <= endRowIndex; i++){
            maxOtherHeight = 0;
            for(var j = 0; j < table.getColumns().length; j++){
                if(j == offset.tableColIndex) continue;
    
                otherCell = table.getRows(i).getCells(j);
                if(!otherCell.__pageList) continue;
    
                pHeight = getPageHeight(otherCell.__pageList);
                
                if(otherCell.style){
                    var padding = converter.parsePoM(otherCell.style.padding);
                    pHeight += padding.top + padding.bottom;
                }
    
                if(maxOtherHeight < pHeight){
                    maxOtherHeight = pHeight;
                }
            }
            sumHeight += maxOtherHeight;
        }

        //小于其他页面高度
        if(pageHeight < sumHeight && 
            sumHeight >= height){
            return false;
        }

        return true;
    }

    /**
     * 获取页面高度集合
     * @param {*} pageList 
     * @returns 
     */
    var getPageHeight = function(pageList){
        var startIndex = pageList.getFirstPage().getIndex();
        var endIndex = pageList.getLastPage().getIndex();

        var pageHeight = 0;
        for(var i = startIndex; i <= endIndex; i++){
            pageHeight += pageList.getPage(i).getBoundRect("body").height;
        }

        return pageHeight;
    }

    /**
     * 插入动作后处理
     * @param {*} elements 
     * @param {*} offset 
     * @returns 
     */
    var afterProcessForInsert = function(elements, offset){
        for(var i in elements){
            if(!elements[i].main || !elements[i].__boundRect) continue;

            return {
                element: elements[i].element,
                offset: {
                    ...offset,
                    ...elements[i].offset
                }
            }
        }

        return {
            element: elements[elements.length - 1].element,
            offset: {
                ...offset,
                ...elements[elements.length - 1].offset
            }
        }
    }

    /**
     * 删除动作后处理
     * @param {*} elements 
     * @param {*} offset 
     * @param {*} pageList
     * @param {*} type
     * @returns 
     */
    var afterProcessForDelete = function(elements, offset){
        var eleOffset = null;

        for(var i in elements){
            if(!eleOffset && elements[i].offset && elements[i].offset.pageIndex){
                eleOffset = elements[i].offset;
            }

            if(!elements[i].element.__boundRect) continue;

            return {
                element: elements[i].element,
                offset: elements[i].offset
            }
        }

        var nextSibling = elements[0].element.__prevSibling;
        if(!nextSibling){
            nextSibling = elements[0].element.__nextSibling;
        }
        
        eleOffset = getElementOffset(nextSibling, true);

        //到这说明元素全部被删除
        var result = {
            element: nextSibling,
            offset: eleOffset
        };

        //表示发生跨页面排版
        if(eleOffset.pageIndex != offset.pageIndex){
            result.pageChangeRange = [eleOffset.pageIndex, offset.pageIndex];
        }

        return result;
    }

    /**
     * 获取元素的偏移量
     * @param {*} element 
     * @param {*} fromEnd true 从元素末尾计算
     */
    var getElementOffset = function(element, fromEnd){
        let offset = {};
        let row = null;

        if(fromEnd){
            row = element.__rows[element.__rows.length - 1];
        }else{
            for(let i in element.__rows){
                row = element.__rows[i];
                break;
            }
        }

        row = row[row.length - 1];
        
        offset.pageIndex = row.getPageIndex();
        offset.rowIndex = row.getIndex();
        offset.elementIndex = row.indexOf(element);
        
        let pIndex = offset.pageIndex;
        let cell = row.getPage().getOwnerElement();
        while(cell){
            offset = { next: offset };

            let table = cell.parent.parent;
            row = table.__rows[pIndex];
            row = row[row.length - 1];
            
            offset.next.tableRowIndex = cell.__rowIndex;
            offset.next.tableColIndex = cell.__colIndex;

            offset.pageIndex = row.getPageIndex();
            offset.rowIndex = row.getIndex();
            offset.elementIndex = row.indexOf(table);

            cell = row.getPage().getOwnerElement();
        } 

        if(element._sType == "sText"){
            offset.range = {
                start: element.innerText.length - 1,
                end: element.innerText.length - 1
            };
        }else{
            offset.range = {
                start: 0,
                end: 0
            };
        }
        
        return offset;
    }

    /**
     * 修改动作后处理
     * @param {*} elements 
     * @param {*} offset 
     */
    var afterProcessForModify = function(elements, offset){
        var el = null;
        if(elements.length == 1){
            el = elements[0];
            delete el.element.__mutate;
            return {
                element: el.element,
                offset: el.offset ? el.offset : offset
            }
        }else{
            var result = null;
            for(var i = elements.length - 1; i >= 0; i--){
                el = elements[i];

                //保证变异标记被删除
                delete el.element.__mutate;

                if((!el.mutate && !el.mutateNew) || el.notLocate) {
                    continue;
                }

                if(!result){
                    result = {
                        element: el.element,
                        offset: el.offset ? el.offset : offset
                    }
                }
            }

            return result;
        }
    }

    /**
     * 替换动作后处理
     * @param {*} elements 
     * @param {*} offset 
     */
    var afterProcessForReplace = function(elements, offset){
        var el = null;
        if(elements.length == 1){
            el = elements[0];
            delete el.element.__mutate;
            return {
                element: el.element,
                offset: el.offset ? el.offset : offset
            }
        }else{
            var result = null;
            for(var i = elements.length - 1; i >= 0; i--){
                el = elements[i];

                delete el.element.__mutate;

                if(el.delete) {
                    continue;
                }

                if(!result){
                    result = {
                        element: el.element,
                        offset: el.offset ? el.offset : offset
                    }
                }
                
                break;
            }

            return result;
        }
    }

    /**
     * 不用于定位的元素，非内容元素
     */
    var noneLocateElements = ["sTableRow", "sTableColumn", "sTableCell"];

    /**
     * 覆盖原始页并返回相关信息
     * @param {*} element 当前元素
     * @param {*} offset 变异元素偏移量
     * @param {*} rowOffset 变异页偏移量
     * @param {*} types
     * @param {*} pageList 
     * @param {*} tempPageList 
     * @param {*} actType
     * @returns 
     */
    var rewritePage = function(element, offset, rowOffset, 
        types, pageList, tempPageList, actType){

        rewritePageByTempPage.call(this, rowOffset, 
            types, pageList, tempPageList);

        var result = null;
        var row = null;

        //根据元素计算当前位置
        if(element && noneLocateElements.indexOf(element._sType) < 0){
            let isDelete = actType == ssDict.sActionType.DELETE;
            var eleOffset = getOffsetForElement(element, offset, isDelete);

            if(!offset.next){
                row = element.__rows[eleOffset.pageIndex][eleOffset.rowIndex];
                result = computeElementOffset.call(this, row, element, 0, eleOffset.contentIndex + 1);
        
                result.pageIndex = eleOffset.pageIndex;
                result.rowIndex = eleOffset.rowIndex;
                result.elementIndex = row.getElementList().indexOf(element);
                result.contentIndex = eleOffset.contentIndex;
                result.absoluteIndex = eleOffset.absoluteIndex;
            }else{
                result = this.locateElementOffset(eleOffset, element);
                result.pageIndex = eleOffset.pageIndex;
            }

            result.ref = element;
            result.pageRange = [];
            
            for(var i = tempPageList.getFirstPage().getIndex(); 
                i <= tempPageList.getLastPage().getIndex(); i++){
                result.pageRange.push(i);
            }
        }

        return result;
    }

    /**
     * 覆盖原始页并返回相关信息
     * @param {*} rowOffset 变异页偏移量
     * @param {*} types
     * @param {*} pageList 
     * @param {*} tempPageList 
     * @returns 
     */
    var rewritePageByTempPage = function(rowOffset, 
        types, pageList, tempPageList){
        //将新排版的内容覆盖旧的排版内容
        var firstIndex = tempPageList.getFirstPage().getIndex();
        var lastIndex = tempPageList.getLastPage().getIndex();
        var type = null;
        var result = {
            pageRange: []
        };

        //页眉、页脚只执行第一页
        var isRun = {head: false, foot: false};

        for(var i = firstIndex; i <= lastIndex; i++){
            var tempPage = tempPageList.getPage(i);

            var oldPage = pageList.getPage(i);
            if(!oldPage){
                oldPage = pageList.insertPage(pageList.getFirstPage().getOption());
                oldPage.setBoundRect(pageList.getFirstPage().getBoundRect());
            }

            for(var j = 0; j < types.length; j++){
                type = types[j];

                if(isRun[type]){
                    continue;
                }

                let range = {
                    replaceAll: i < lastIndex ? true : rowOffset.replaceAll
                };

                if(isRun[type] === false){
                    range.replaceAll = true;
                    range.start = 1;
                    range.end = tempPage.getRowCount(type);

                    let rowcount = oldPage.getRowCount(type);
                    if(rowcount > range.end){
                        range.end = rowcount;
                    }

                    isRun[type] = true;
                }else{
                    range.start = i == rowOffset.startPageIndex 
                        ? rowOffset.startRowIndex 
                        : 1;

                    if(i == rowOffset.endPageIndex){
                        range.end = rowOffset.endRowIndex
                    }else{
                        range.end = tempPage.getRowCount(type);

                        if(range.replaceAll){
                            let rowcount = oldPage.getRowCount(type);
                            if(rowcount > range.end){
                                range.end = rowcount;
                            }
                        }
                    }
                }

                //将临时页的元素放入旧页
                tempPage.mergeTo(type, oldPage, range);
            }

            result.pageRange.push(i);

            //移动绝对定位元素
            tempPage.moveAbsoluteElement(oldPage);
        }

        if(rowOffset.replaceAll){
            //删除多余页
            let delPages = [];
            let endPageIndex = pageList.getLastPage().getIndex();

            for(let i = rowOffset.endPageIndex + 1; i <= endPageIndex; i++){
                delPages.push(i);
            }

            pageList.removePages(delPages);

            //删除多余行
            let page = pageList.getPage(rowOffset.endPageIndex);
            page.removeGreatThan("body", rowOffset.endRowIndex);
        }

        return result;
    }

    /**
     * 定位元素的坐标偏移量
     * @param {*} offset 布局偏移量
     * @param {*} element 元素
     * @param {*} isSelf 定位本身
     */
    this.locateElementOffset = function(offset, element){
        if(!offset || !element) return null;

        //将当前偏移量转成数组
        let arr = ost.splitOffset(offset, true);
        let index = arr.length - 1;
        let isBody = offset.position == "body" || !offset.position;
        let pIndex = 1;

        //指向最内部偏移量
        let next = arr[index];
        pIndex = isBody ? next.pageIndex : 1;

        let row = null;
        if(element.__rows[pIndex]){
            row = element.__rows[pIndex][next.rowIndex];
        }

        let contentIndex =  arr[index].contentIndex;

        contentIndex = contentIndex == null ? -1 : contentIndex;

        let result = computeElementOffset.call(this, row, element, 
            contentIndex, contentIndex + 1);

        while(row != null){
            let cell = row.getPage().getOwnerElement();
            if(cell != null){
                pIndex = isBody ? row.getPageIndex() : 1;

                let rect = cell.__boundRect[pIndex];
                rect = rect[rect.length - 1];

                result.left += rect.left;
                result.top += rect.top;

                if(cell.__boundRect.verticalOffsetHeight){
                    result.top += cell.__boundRect.verticalOffsetHeight;
                }

                let table = cell.parent.parent;

                pIndex = isBody ? pIndex : 1;
                row = table.__rows[pIndex];
                row = row[row.length - 1];
                
                let computeOffset = computeElementOffset.call(this, row, table, 0, 0);
                result.left += computeOffset.left;
                result.top += computeOffset.top;
            }else{
                row = null;
            }
        }

        return result;
    }

    /**
     * 根据绝对内容序号找到所属行
     * @param {*} element 
     * @param {*} offset 
     */
    var rectifyRowByAbsoluteIndex = function(element, offset){
        if(element.__texts){
            let textCount = 0;
            for(let i in element.__texts){
                for(let j in element.__texts[i]){
                    if(offset.absoluteIndex >= textCount - 1 && 
                        offset.absoluteIndex <= textCount - 1 + element.__texts[i][j].length){
                        offset.pageIndex = parseInt(i);
                        offset.rowIndex = parseInt(j);
                        return element.__rows[i][j];
                    }
                }
            }
            return null;
        }else{
            let row = element.__rows[element.__rows.length - 1];
            return row[row.length - 1];
        }
    }

    /**
     * 定位元素的坐标偏移量
     * @param {*} element 元素
     * @param {*} absoluteIndex 元素内容的绝对序号 
     */
    this.locateElementOffset2 = function(element, absoluteIndex){
        let offset = {};

        if(element._sType == "sText"){
            let length = 0;
            for(let i in element.__texts){
                for(let j in element.__texts[i]){
                    if(length + element.__texts[i][j].length > absoluteIndex){
                        offset.pageIndex = parseInt(i);
                        offset.rowIndex = parseInt(j);
                        offset.contentIndex = absoluteIndex - length;
                        break;
                    }
                    length += element.__texts[i][j].length;
                }
            }
        }else{
            for(let i in element.__boundRect){
                for(let j in element.__boundRect[i]){
                    offset.pageIndex = parseInt(i);
                    offset.rowIndex = parseInt(j);
                    offset.contentIndex = absoluteIndex > 0 ? 0 : -1;
                    break;
                }
            }
        }

        return this.locateElementOffset(offset, element);
    }

    /**
     * 根据内容选择范围获取元素偏移量
     * @param {*} element 元素
     * @param {*} offset 
     * @returns 
     */
    this.getOffsetForElement = function(element, offset){
        return getOffsetForElement(element, offset);
    }

    /**
     * 根据内容选择范围获取元素偏移量
     * @param {*} element 元素
     * @param {*} eleOffset
     * @param {*} useStart true:使用start定位 默认false
     * @returns 
     */
    var getOffsetForElement = function(element, eleOffset, isDelete){
        var length = 0;
        var offset = {
            pageIndex: 0,
            rowIndex: 0,
            contentIndex: -1,
            absoluteIndex: 0
        };

        var range = eleOffset.range;
        if(!range && eleOffset.next){
            range = ost.extractOffset(eleOffset, true).range;
        }

        if(element._sType == "sText"){
            var pos = isDelete ? range.start + 1 : range.end;
            
            pos = pos < 0 ? 0 : pos;
            pos = pos > element.innerText.length ? element.innerText.length : pos;

            var text = null;
            var find = false;
    
            for(var i in element.__texts){
                if(!element.__texts[i]) continue;
                offset.pageIndex = parseInt(i);
    
                for(var j in element.__texts[i]){
                    text = element.__texts[i][j];
                    
                    if(text == null) continue;
                    offset.rowIndex = parseInt(j);
    
                    if(pos >= length && 
                        pos <= length + text.length){
                        offset.pageIndex = parseInt(i);
                        offset.rowIndex = parseInt(j);
                        offset.contentIndex = pos - length - 1;
                        offset.absoluteIndex += offset.contentIndex;
    
                        find = true;
    
                        break;
                    }
    
                    length += element.__texts[i][j].length;
                    offset.absoluteIndex = length;
                }
    
                if(find) break;
            }
        }else{ 
            offset.pageIndex = element.__boundRect.length - 1;
            offset.rowIndex = element.__boundRect[offset.pageIndex].length - 1;
            offset.contentIndex = range ? range.end : -1;
            offset.absoluteIndex = offset.contentIndex;
        }

        if(eleOffset.next){
            //指向最内部偏移量，必须用offset, 因为排版后eleOffset的指向已经不准确了
            let row = element.__rows[offset.pageIndex][offset.rowIndex];
            let pageIndex = offset.pageIndex;

            while(row != null){
                let cell = row.getPage().getOwnerElement();
                if(cell != null){
                    offset = { next: offset };

                    let table = cell.parent.parent;
                    let rows = table.__rows[pageIndex];
                    row = rows[rows.length - 1];

                    offset.pageIndex = row.getPageIndex();
                    offset.rowIndex = row.getIndex();
                    offset.elementIndex = row.indexOf(table);
                }else{
                    row = null;
                }
            }
        }        

        return offset;
    }

    /**
     * 删除指定行号之后的包围盒
     * @param {*} element 
     * @param {*} pageIndex 
     * @param {*} index 
     */
    var deleteBoundRectGreatIndex = function(element, pageIndex, index){
        if(!element.__boundRect) return;

        var boundRect = [];
        var rows = [];
        var texts = null;
        var flg = false;

        for(var i = pageIndex; i > 0; i--){
            if(!element.__boundRect[i]) break;

            var rowIndex = i == pageIndex ? (index - 1) : element.__boundRect[i].length - 1;

            for(var j = rowIndex; j > 0; j--){
                if(!element.__boundRect[i][j]) continue;

                if(!boundRect[i]){
                    boundRect[i] = [];
                }

                boundRect[i][j] = element.__boundRect[i][j];

                if(!rows[i]){
                    rows[i] = [];
                }

                rows[i][j] = element.__rows[i][j];

                if(element.__texts){
                    if(!texts){
                        texts = [];
                    }

                    if(!texts[i]){
                        texts[i] = [];
                    }

                    texts[i][j] = element.__texts[i][j];
                }

                flg = true;
            }
        }

        if(flg){
            element.__boundRect = boundRect;
            element.__rows = rows;
            if(texts){
                element.__texts = texts;
            }
        }else{
            delete element.__boundRect;
            delete element.__texts;
            delete element.__rows;
        }
    }

    /**
     * 获取指定行号之前的元素文本长度
     * @param {*} element 文本元素
     * @param {*} pageIndex 指定页码
     * @param {*} index 指定行号
     * @returns 
     */
    var getTextLessIndexLength = function(element, pageIndex, index){
        if(element._sType != "sText" || !element.__texts){
            return 0;
        }

        var length = 0;
        var ind = null;

        for(var i = pageIndex; i > 0; i--){
            if(!element.__texts[i]) break;
            ind = i == pageIndex 
                ? index - 1 
                : element.__texts[i].length - 1;
            for(var j = ind; j > 0; j--){
                if(!element.__texts[i][j]) break;
                length += element.__texts[i][j].length;
            }
        }

        return length;
    }

    /**
     * 元素重排
     * @param {*} element 元素
     * @param {*} parentRect 父元素包围盒
     * @param {*} render 布局引擎
     * @param {*} type 页面布局类型：body(页体,默认) head(页眉) foot(页脚) 
     */
    var reflow = function(element, parentRect, render, type, option){
        try{
            var newpage = null;

            switch(element._sType){
                case "sText":
                    newpage = render.textFormat(element, parentRect, type);
                    break;
                case "sParagraph":
                    newpage = render.paragraphFormat(element, parentRect, type);
                    break;
                case "sBreakline":
                    newpage = render.breaklineFormat(element, type);
                    break;
                case "sLayer":
                    newpage = render.layerFormat(element, type);
                    break;    
                case "sInputBegin":
                case "sInputEnd":
                    newpage = render.inputAreaFormat(element, parentRect, type, option);
                    break;  
                case "sTable":
                    option = option ? option : {};
                    option.reformat = true;
                    option.ignoreExceed = type != "body";
                    newpage = render.tableFormat(element, parentRect, type, option);
                    break;
            }
        }catch(e){
            console.error(e);
        }

        return newpage;
    }

    /**
     * 计算当前元素所在的偏移量
     * @param {*} row 当前行
     * @param {*} element 元素
     * @param {*} startIndex 内容开始序号 
     * @param {*} endIndex 内容结束序号
     * @returns 
     */
    this.computeElementOffset = function(row, element, startIndex, endIndex){
        return computeElementOffset.call(this, row, element, startIndex, endIndex);
    }

    /**
     * 计算当前元素所在的偏移量
     * @param {*} row 当前行
     * @param {*} element 元素
     * @param {*} startIndex 内容开始序号 
     * @param {*} endIndex 内容结束序号
     * @returns 
     */
    var computeElementOffset = function(row, element, startIndex, endIndex){
        if(element._sType == "sText"){
            var left = 0;
            var isJustify = row.resetTextAlign(row.getParagraphStyle(element), row.isEndWithParagraph());
            var boundRect = row.getActualBoundRect(element);

            var length = 0;
            var text = row.getText(element);
            var trimText = text.substring(0, startIndex);
            var metrics = null;
    
            if(trimText){
                metrics = painter.measureText(element, trimText);
                left += metrics.width;
                length += trimText.length;
            }
    
            trimText = text.substring(startIndex, endIndex);
            length += trimText.length;
    
            if(trimText){
                metrics = painter.measureText(element, trimText);
                left += metrics.width;
            }
    
            if(isJustify){
                left += boundRect.letterSpacing * (
                    endIndex < text.length || element.__hasNextVisibleText 
                    ? length 
                    : length > 0 ? length - 1 : 0
                );
            }

            var rect = row.getElementBoundRect(element);
            rect.top += row.getBoundRect().top;
    
            return {
                left: boundRect.left + left,
                top: rect.top,
                text: text,
                boundRect: boundRect //rect
            };
        }else if(element._sType == "sLayer"){
            var left = 0;
            var boundRect = row.getActualBoundRect(element);
            var rect = row.getElementBoundRect(element);

            rect.top += row.getBoundRect().top;
    
            endIndex = endIndex < 0 ? 0 : endIndex > 1 ? 1 : endIndex;
            
            return {
                left: boundRect.left + endIndex * boundRect.width,
                top: rect.top,
                boundRect: rect
            };
        }else if(element._sType == "sTable"){
            var left = 0;
            var boundRect = row.getActualBoundRect(element);
            var rect = row.getElementBoundRect(element);
            
            rect.top += row.getBoundRect().top;
    
            endIndex = endIndex < 0 ? 0 : endIndex > 1 ? 1 : endIndex;

            return {
                left: boundRect.left + left + endIndex * boundRect.width,
                top: rect.top,
                boundRect: rect
            };
        }else {
            var left = 0;
            var boundRect = row.getActualBoundRect(element);
            var rect = row.getElementBoundRect(element);
            
            rect.top += row.getBoundRect().top;

            endIndex = endIndex < 0 ? 0 : endIndex > 1 ? 1 : endIndex;

            return {
                left: boundRect.left + endIndex * boundRect.width,
                top: rect.top,
                boundRect: rect
            };
        }
    }

    /**
     * 段落排版
     * @param {*} paragraph 段落元素
     * @param {*} type 页面布局类型：body(页体,默认) head(页眉) foot(页脚) 
     * @returns 返回值如下：
     * 0 无需新增分页
     * 1 需新增分页且当前文本不在当前页 
     * 2 需新增分页，当前文本元素会被分隔到当前页和新增页
     */
    this.paragraphFormat = function(paragraph, parentRect, type){
        if(ifHiddenThenAdd(paragraph, type)) return;

        insertRowIfNeed.call(this, paragraph, type);
        
        var row = page.getLastRow(type);
        if(row.getVisEleCount() == 0){
            var text = new sText();
            text.__paragraphIndex = paragraph.__paragraphIndex;
            this.textFormat(text, parentRect, type);
        }

        row.addParagraph(paragraph);

        return 0;
    }

    /**
     * 换行符排版
     * @param {*} breakline 
     * @param {*} type 
     * @returns 
     */
    this.breaklineFormat = function(breakline, type){
        if(ifHiddenThenAdd(breakline, type)) return;

        page.getLastRow(type).addBreakline(breakline);
        return 0;
    }

    /**
     * 层元素排版
     * @param {*} layer 层元素
     * @param {*} type 页面布局类型：body(页体,默认) head(页眉) foot(页脚) 
     * @returns 返回值如下：
     * 0 无需新增分页
     * 1 需新增分页
     */
    this.layerFormat = function(layer, type){
        if(ifHiddenThenAdd(layer, type)) return;

        //非绝对定位，当做行内元素处理
        if(layer.style.position != "absolute"){

            //上一行的挂载元素
            if(layer.__attachElements){
                reformatAttachElement(layer.__attachElements, this, type);
                delete layer.__attachElements;
            }
            
            //根据需要插入新行
            insertRowIfNeed.call(this, layer, type);

            var margin = converter.parsePoM(layer.style.margin);
            var boundRect = {
                left: margin.left,
                top: margin.top,
                width: layer.style.width ? layer.style.width : page.getBoundRect(type).width,
                height: layer.style.height
            }

            //计算放入当前行之后文本的包围盒
            var measureRect = page.getLastRow(type).measureElement(boundRect, layer);
            
            //宽高是否溢出
            var exceed = isExceed.call(this, measureRect, layer, type);
            if(exceed == 1) {
                if(!page.getLastRow(type).isVisualEmpty(true)){
                    //如果宽度溢出，则挪到下一行
                    measureRect = page.insertRow(type).measureElement(boundRect, layer);
                    //判断这一行会不会发生高度或宽度溢出
                    exceed = isExceed.call(this, measureRect, layer, type);
                }
            }

            //如果高度溢出，则返回新增页面的状态
            if(exceed > 1){
                if(page.getLastRow(type).getIndex() > 1){
                    if(exceed == 2){
                        //只是高度溢出，则将当前行所有元素带到下一行
                        layer.__attachElements = page.getLastRow(type).getElementList();
                        deleteBoundAttachElement(layer.__attachElements, type);
                        page.removeLastRow(type);
                        return 1;
                    }else{
                        page.getLastRow(type).removeParagraphOnlyRelFor(layer);
                        return 1;
                    }
                }else if(exceed > 2){
                    //宽高都溢出
                    return 1;
                }

                if(type != "body"){
                    return exceed;
                }
            }

            var index = page.getLastRow(type).getIndex();
            var pageIndex = page.getIndex();

            layer.__boundRect = [];
            layer.__boundRect[pageIndex] = [];
            layer.__boundRect[pageIndex][index] = { ...measureRect };

            page.getLastRow(type).addElement(layer);

            if(layer.presentType == ssDict.sPresentType.PAGE_BREAK){
                return 9;
            }
        }else{
            page.addAbsoluteElement(layer, type);
        }

        return 0;
    }

    /**
     * 输入域排版
     * @param {*} inputArea 输入域对象
     * @param {*} pageRect 父元素包围盒
     * @param {*} type 页面布局类型：body(页体,默认) head(页眉) foot(页脚) 
     * @param {*} option 可选项
     */
    this.inputAreaFormat = function(inputArea, parentRect, type, option){
        if(ifHiddenThenAdd(inputArea, type)) return;

        option = option ? option : {};
        
        //上一行的挂载元素
        if(inputArea.__attachElements){
            reformatAttachElement(inputArea.__attachElements, this, type);
            delete inputArea.__attachElements;
        }

        if(inputArea._sType == "sInputBegin"){
            if(option.nextElement && option.nextElement._sType == "sText"){
                inputArea.tagView.style = option.nextElement.style;
            }
        }else if(inputArea._sType == "sInputEnd"){
            if(option.prevElement && option.prevElement._sType == "sText"){
                inputArea.tagView.style = option.prevElement.style;
            }
        }

        if(inputArea.tagView._sType == "sText"){
            option.notAddLayout = true;

            var newPage = this.textFormat(inputArea.tagView, parentRect, type, option);
            if(newPage > 0){
                return newPage;
            }

            inputArea.__boundRect = [];

            var text = inputArea.tagView;
            var rect = null;
            for(var i in text.__boundRect){
                inputArea.__boundRect[i] = [];
    
                for(var j in text.__boundRect[i]){
                    if(page.getLastRow(type).getIndex() < parseInt(j)){
                        page.insertRow(type);
                    }
                    rect = {...text.__boundRect[i][j]};
                    inputArea.__boundRect[i][j] = rect;
                }
            }
    
            page.getLastRow(type).addElement(inputArea);
        }
    }

    /**
     * 表格排版
     * @param {*} table 表格元素
     * @param {*} parentRect 父元素包围盒
     * @param {*} type 页面布局类型：body(页体,默认) head(页眉) foot(页脚) 
     * @param {*} opt 可选项
     * @returns 0不跨页 1跨页 
     */
    this.tableFormat = function(table, parentRect, type, opt){
        if(ifHiddenThenAdd(table, type)) return;

        opt = opt ? opt : {};

        //忽略越界
        var ignoreExceed = opt.ignoreExceed;

        //表格分页范围
        if(table.__pageRange && !ignoreExceed){
            this.getPage().getLastRow(type).addElement(table);
            if(table.__pageRange.end > this.getPage().getIndex()){
                return 1;
            }
            delete table.__pageRange;
            return 0;
        }

        //根据需要插入新行
        var isNewRow = insertRowIfNeed.call(this, table, type);

        //表格宽度
        var width = 0;
        var colWidths = [];
        var cols = table.getColumns();
        
        //统计列宽
        for(var k = 0; k < cols.length; k++){
            colWidths.push(parseFloat(cols[k].style.width));
            width += colWidths[k];
        }

        //定义表格包围盒
        var tableRect = {
            left: 0,
            top: 0,
            width: width,
            height: 0
        };

        //行内元素
        if(table.style.display != "block"){
            if(isExceed.call(this, tableRect, table, type) == 1){
                this.getPage().insertRow(type);
            }
        }

        //分析表格表头
        parseTableHeadRow.call(this, table);

        //测量表格放入当前行后的包围盒属性
        var row = this.getPage().getLastRow(type);
        var measureRect = row.measureElement(tableRect, table);
        
        //分析表格行，并返回相关属性
        parseTableRow.call(this, table, colWidths, measureRect, parentRect, type, opt);
        
        var pIndex = this.getPage().getIndex();
        
        //当前行加入表格（如果表格范围不在当前页，则不能加入）
        if(table.__boundRect[pIndex]){
            this.getPage().getLastRow(type).addElement(table);
        }
        //之前插入新行，但表格范围不在此页，则该行需要删除掉
        else if(isNewRow){
            this.getPage().removeLastRow(type);
        }

        //单元格内编辑
        if(matchCellContentEdit(opt, table)){
            opt.cellContentEdit.startPageIndex = table.__pageRange.begin;
        }

        //表格结束页大于当前页
        if(table.__pageRange.end > this.getPage().getIndex()){
            return 1;
        }

        delete table.__pageRange;

        return 0;
    }

    /**
     * 当前表格是否匹配内容编辑单元格所在表格
     * @param {*} opt 
     * @param {*} table 
     * @returns 
     */
    var matchCellContentEdit = function(opt, table){
        return opt.cellContentEdit && opt.cellContentEdit.table === table;
    }

    /**
     * 分析表格表头行(表头行必须连续，并且要从首行开始)
     * @param {*} table 
     */
    var parseTableHeadRow = function(table){
        let rows = table.getRows();
        let row = null;
        let headCount = 0;
        let headRows = [];
        
        for(let i = 0; i < rows.length; i++){
            row = rows[i];
            
            if(!row.style) continue;
            
            if(row.head === true || row.head === "true"){
                //首行必须是表头
                if(!rows[0].head){
                    row.head = false;
                }
                //不允许出现不连续的表头行
                else if(i > 0 && !rows[i - 1].head){
                    row.head = false;
                }else{
                    row.head = true;
                    headRows.push(i);
                    headCount++;
                }
            }else{
                delete row.head;
            }
        }

        //不能全部是表头行
        if(headCount == rows.length){
            let lastRow = rows[rows.length - 1];
            delete lastRow.head;

            headRows.splice(rows.length - 1, 1);
        }

        if(headRows.length > 0){
            table.__headRows = headRows;
        }
    }

    /**
     * 分析表格行
     * @param {*} table 表格元素
     * @param {*} colWidths 表格列宽集合
     * @param {*} tableRect 表格包围盒
     * @param {*} pageRect 页面包围盒
     * @param {*} type 区域类型
     * @param {*} opt 可选项
     */
    var parseTableRow = function(table, colWidths, tableRect, pageRect, type, opt){
        opt = opt ? opt : {};

        //内容移动标志，表示表格本身无任何变化，只是发生移动
        //此时不需要对表格单元格内部重新进行排版
        if(!opt.contentMove){
            //内容编辑标志，表示某个单元格内容发生变化
            if(!matchCellContentEdit(opt, table)){
                //分析合并单元格
                parseSpanCell(table);
            }
    
            //对所有单元格内容进行排版
            cellsFormat(table, colWidths, type, opt);
        }

        //用于分页的包围盒
        var rect = {
            left: 0,
            top: 0,
        }

        //表格分页范围
        table.__pageRange = {
            begin: 0, 
            end: 0
        };

        //下一行初始选项值
        var nextRowOpt = {
            //当前表格行序号
            index: 0,
            //合并单元格排版信息
            formatSpanCellInfo: {
                //是否排版
                isRun: {}
            },
            //用于中间计算的虚拟行
            vRow: null,
            //页面区域类型
            type: type,
            //表头排版属性
            head: {
                //表头高度
                height: 0,
                //表头占据的页码集合
                pageRange: [],
                //表头占据的表格行序号
                tableRowRange: [],
                //设置表头当前的应用页
                apply: {} 
            },
            //记录当前到达的最小页数
            minPageIndex: null,
            //表格包围盒
            tableRect: tableRect,
            //分页包围盒
            pageRect: pageRect,
            //当前页码
            pageIndex: this.getPage().getIndex(),
            //当前行码
            rowIndex: this.getPage().getLastRow(type).getIndex(),
            //行总宽度
            rowWidth: sumColWidth(colWidths, 0, colWidths.length),
            //当前页排版剩余高度
            height: pageRect.top + pageRect.height - tableRect.top,
            //性能优化参数
            performanceOptz: {
                ...opt
            }
        };

        //外部传入的页面包围盒
        if(opt.pageRect){
            nextRowOpt.pageRect = opt.pageRect;
        }

        //表格行
        var rows = table.getRows();

        //格式化行
        formatRows.call(
            this, 
            rows, 
            colWidths, 
            table, 
            rect, 
            nextRowOpt
        );

        table.__boundRect = [];

        var pageIndex = null;

        //根据行包围盒，生成表格包围盒
        for(var i = 0; i < rows.length; i++){
            row = rows[i];
            if(!row.__boundRect) continue;
            mergeTableElement(table, row.__boundRect, (tRect, rowRect, opt)=>{
                tRect.left = tableRect.left;

                if(!opt.init){
                    tRect.height += rowRect.height;
                }

                if(table.__headRows && pageIndex && pageIndex != opt.pageIndex){
                    tRect.top -= nextRowOpt.head.height;
                    tRect.height += nextRowOpt.head.height;
                    tRect.headHeight = nextRowOpt.head.height;
                }

                pageIndex = opt.pageIndex;
            }, 2);
        }
    }

    /**
     * 格式化行
     * @param {*} rows 行集合
     * @param {*} colWidths 列宽集合
     * @param {*} table 表格
     * @param {*} tableRect 表格包围盒
     * @param {*} rect 分页包围盒
     * @param {*} nextRowOpt 行选项
     */
    var formatRows = function(rows, colWidths, table, rect, nextRowOpt){
        let row = null;
        let po = nextRowOpt.performanceOptz;
        let startTableRowIndex = null;

        let nothingCount = 0;
        let moveCount = 0;
        let formatCount = 0;

        //单个单元格编辑状态
        if(matchCellContentEdit(po, table)){
            let startPageIndex = null;

            row = rows[po.cellContentEdit.tableRowIndex];

            //找出重新排版的起始页
            for(let i in row.__boundRect){
                startPageIndex = parseInt(i);
                break;
            }

            //找出重新排版的表格起始行
            for(let j = 0; j < rows.length; j++){
                row = rows[j];

                //是表头行
                if(row.head){
                    let pIndex = row.__boundRect.length - 1;
                    let rect = row.__boundRect[pIndex];

                    nextRowOpt.head.height += rect[rect.length - 1].height;

                    if(nextRowOpt.head.pageRange.indexOf(pIndex) < 0){
                        nextRowOpt.head.pageRange.push(pIndex);
                    }

                    nextRowOpt.head.tableRowRange.push(j);
                }

                if(!row.__boundRect[startPageIndex]) continue;
                
                if(startTableRowIndex == null){
                    startTableRowIndex = j;
                }

                if(!row.head){
                    break;
                }
            }

            if(nextRowOpt.head.pageRange.length == 1 && 
                nextRowOpt.head.pageRange.indexOf(startPageIndex) < 0){

                nextRowOpt.head.apply[startPageIndex] = nextRowOpt.head.height;
                nextRowOpt.height -= nextRowOpt.head.height;

            }

            for(let i in rows[startTableRowIndex].__boundRect){
                for(let j in rows[startTableRowIndex].__boundRect[i]){
                    nextRowOpt.rowIndex = parseInt(j);
                    break;
                }
                break;
            }

            nextRowOpt.index = startTableRowIndex;
            nextRowOpt.pageIndex = startPageIndex;
        }else if(po.contentMove){
            po.cellContentEdit = {
                tableRowIndex: 0
            };
            startTableRowIndex = 0;
        }else{
            startTableRowIndex = 0;
        }

        let oldPageIndex = -1;
        let pageIndex = -1;
        let tableRowIndex = 0;
        let needFormat = true;
        let moveProp = null;
        let formatRange = null;
        let pageRect = nextRowOpt.pageRect;
        
        //对单元格进行分页
        for(let k = startTableRowIndex; k < rows.length; k++){
            tableRowIndex = parseInt(k);
            row = rows[tableRowIndex];

            if(row.style && row.style.display == "none") {
                nextRowOpt.pageIndex = pageIndex > 0 
                    ? pageIndex 
                    : nextRowOpt.pageIndex;
                nextRowOpt.index = tableRowIndex + 1;

                if(po && po.cellContentEdit){
                    po.cellContentEdit.tableRowIndex = nextRowOpt.index;
                }

                continue;
            }

            row.__index = k;
            
            needFormat = true;
            moveProp = null;

            if(po.cellContentEdit){
                if(k < po.cellContentEdit.tableRowIndex){
                    needFormat = false;
                }else if(k > po.cellContentEdit.tableRowIndex){
                    let rowRange = getSpanCellRowRange(row, tableRowIndex, table);

                    if(!formatRange){
                        formatRange = rowRange;
                    }else if(rowRange){
                        if(formatRange.begin > rowRange.begin){
                            formatRange.begin = rowRange.begin;
                        }
                        
                        if(formatRange.end < rowRange.end){
                            formatRange.end = rowRange.end;
                        }
                    }

                    let notInRange = !formatRange || (
                        formatRange &&
                        (formatRange.begin > k ||
                        formatRange.end < k)
                    );

                    if(notInRange && !isTableRowExceed(row, nextRowOpt)){
                        needFormat = false;
                        moveProp = {
                            pageIndex: row.__boundRect.length - 1,
                            rowIndex: row.__boundRect[row.__boundRect.length - 1].length - 1
                        };
                    }
                }
            }

            if(needFormat){                
                nextRowOpt.vRow = {};

                //指定行高
                if(row.style){
                    if(row.style.height){
                        rect.rowHeight = row.style.height;
                    }else{
                        rect.rowHeight = null;
                    }
                }
    
                if(row.__boundRect){
                    //记录重排前的行的起始页
                    for(let i in row.__boundRect){
                        oldPageIndex = parseInt(i);
                        break;
                    }
                    delete row.__boundRect;
                }
    
                nextRowOpt.minPageIndex = null;

                //格式化当前行单元格
                formatCells.call(
                    this, 
                    row, 
                    tableRowIndex, 
                    colWidths, 
                    rect, 
                    table, 
                    nextRowOpt
                );
    
                if(!row.__boundRect){
                    if(nextRowOpt.vRow.__boundRect){
                        row.__boundRect = nextRowOpt.vRow.__boundRect;
                    }else{
                        continue;
                    }
                }
                //该行除了合并单元格之外，其他都是不可见单元格
                else {
                    let pInd = nextRowOpt.vRow.__boundRect.length - 1;
                    let rInd = nextRowOpt.vRow.__boundRect[pInd].length - 1;

                    if(row.__boundRect[pInd] && 
                       row.__boundRect[pInd][rInd] &&
                      !row.__boundRect[pInd][rInd].height){
                        row.__boundRect[pInd][rInd].height = nextRowOpt.vRow.__boundRect[pInd][rInd].height;
                    }
                }
    
                pageIndex = row.__boundRect.length - 1;

                //同一行单元格拉伸至相同高度(除非存在跨行单元格)
                resizeCellInRow(table, colWidths, row, tableRowIndex, pageIndex);

                formatCount++;

            }else if(moveProp){
                if(!rows[k - 1].__boundRect) continue;

                moveTableRow(row, rows[k - 1], moveProp, nextRowOpt);
                moveCount++;
            }else{
                pageIndex = row.__boundRect.length - 1;

                nothingCount++;
            }

            //重新设置下一行初始值
            getElementBoundRect(row, -1, pageIndex, (eleRect, rIndex)=>{
                if(nextRowOpt.pageIndex == pageIndex){
                    nextRowOpt.height -= eleRect.height;
                }else{
                    nextRowOpt.height = pageRect.height - eleRect.height;
                }

                //减去表头高度
                if(nextRowOpt.minusHeadHeight){
                    nextRowOpt.height -= nextRowOpt.minusHeadHeight;
                    delete nextRowOpt.minusHeadHeight;
                }

                nextRowOpt.rowIndex = rIndex;
            });

            nextRowOpt.pageIndex = pageIndex;
            nextRowOpt.index = tableRowIndex + 1;

            setTablePageRange(table, pageIndex);
            if(oldPageIndex && oldPageIndex != pageIndex){
                setTablePageRange(table, oldPageIndex);
            }

            //是表头行
            if(row.head && nextRowOpt.head.tableRowRange.indexOf(tableRowIndex) < 0){
                nextRowOpt.head.height += row.__boundRect[pageIndex][nextRowOpt.rowIndex].height;
                if(nextRowOpt.head.pageRange.indexOf(pageIndex) < 0){
                    nextRowOpt.head.pageRange.push(pageIndex);
                }
            }
        }

        console.log("nothingCount = " + nothingCount);
        console.log("moveCount = " + moveCount);
        console.log("formatCount = " + formatCount);
    }

    /**
     * 设置表格重排页面范围
     * @param {*} table 
     * @param {*} pageIndex 
     */
    var setTablePageRange = function(table, pageIndex){
        if(!table.__pageRange.begin || 
            table.__pageRange.begin > pageIndex){
            table.__pageRange.begin = pageIndex;
        }

        if(table.__pageRange.end < pageIndex){
            table.__pageRange.end = pageIndex;
        }
    }

    /**
     * 获取指定行中的合并单元格的起始表格行和结束表格行集合
     * @param {*} row 
     * @param {*} tableRowIndex
     * @param {*} table
     * @returns 
     */
    var getSpanCellRowRange = function(row, tableRowIndex, table){
        let rowRange = null;
        let cell = null;
        let cells = row.getCells();

        for(let i in cells){
            cell = cells[i];

            if(cell.style.display == "none"){
                cell = getSpanCell(table, tableRowIndex, parseInt(i)).getRef();
            }

            if(isRowSpanCell(cell)){
                if(!rowRange){
                    rowRange = {
                        begin: null,
                        end: null
                    };
                }

                if(!rowRange.begin || rowRange.begin > cell.__rowIndex){
                    rowRange.begin = cell.__rowIndex;
                }

                if(!rowRange.end || rowRange.end < cell.__rowIndex){
                    rowRange.end = cell.__rowIndex + parseInt(cell.rowspan) - 1;
                }
            }
        }

        return rowRange;
    }

    /**
     * 表格行是否越界
     * @param {*} row 
     * @param {*} opt
     */
    var isTableRowExceed = function(row, opt){
        let pageCount = 0;

        for(let i in row.__boundRect){
            pageCount++;
        }
        
        if(pageCount > 1) return true;

        //表格行不在当前页(向上移动导致)
        if(opt.pageIndex < row.__boundRect.length - 1){
            return true;
        }

        let rect = row.__boundRect[row.__boundRect.length - 1];
        rect = rect[rect.length - 1];

        return rect.height > opt.height;
    }

    /**
     * 移动表格行(行不跨页，且不包含合并单元格)
     * @param {*} row 
     * @param {*} prevRow 
     * @param {*} rOpt 
     * @param {*} prOpt
     */
    var moveTableRow = function(row, prevRow, rOpt, prOpt){
        if(!prevRow.__boundRect) return;

        let prevRect = prevRow.__boundRect[prOpt.pageIndex][prOpt.rowIndex];
        let top = prevRect.top + prevRect.height;

        if(!row.__boundRect[prOpt.pageIndex]){
            row.__boundRect[prOpt.pageIndex] = [];
        }

        row.__boundRect[prOpt.pageIndex][prOpt.rowIndex] = row.__boundRect[rOpt.pageIndex][rOpt.rowIndex];
        row.__boundRect[prOpt.pageIndex][prOpt.rowIndex].top = top;

        if(prOpt.pageIndex != rOpt.pageIndex || prOpt.rowIndex != rOpt.rowIndex){
            let rect = row.__boundRect[rOpt.pageIndex];
            delete rect[rOpt.rowIndex];

            for(let j = row.__boundRect[rOpt.pageIndex].length - 1; j > 0; j--){
                if(row.__boundRect[rOpt.pageIndex][j]){
                    row.__boundRect[rOpt.pageIndex].length = parseInt(j) + 1;
                    break;
                }
            }

            if(rect[rect.length - 1] == null){
                delete row.__boundRect[rOpt.pageIndex];
            }
        }

        let cell = null;
        let cells = row.getCells();

        for(let i in cells){
            cell = cells[i];
            if(cell.style.display == "none"){
                continue;
            }

            if(!cell.__boundRect[prOpt.pageIndex]){
                cell.__boundRect[prOpt.pageIndex] = [];
            }

            cell.__boundRect[prOpt.pageIndex][prOpt.rowIndex] = cell.__boundRect[rOpt.pageIndex][rOpt.rowIndex];
            cell.__boundRect[prOpt.pageIndex][prOpt.rowIndex].top = top;

            if(prOpt.pageIndex != rOpt.pageIndex || prOpt.rowIndex != rOpt.rowIndex){
                let rect = cell.__boundRect[rOpt.pageIndex];
                delete rect[rOpt.rowIndex];

                for(let j = cell.__boundRect[rOpt.pageIndex].length - 1; j > 0; j--){
                    if(cell.__boundRect[rOpt.pageIndex][j]){
                        cell.__boundRect[rOpt.pageIndex].length = parseInt(j) + 1;
                        break;
                    }
                }

                if(rect[rect.length - 1] == null){
                    delete cell.__boundRect[rOpt.pageIndex];
                }
            }
        }
    }

    /**
     * 格式化指定行单元格
     * @param {*} row 指定行
     * @param {*} tableRowIndex 表格行序号
     * @param {*} colWidths 列宽集合
     * @param {*} rect 页包围盒
     * @param {*} table 区域类型
     * @param {*} nextRowOpt 行选项
     */
    var formatCells = function(row, tableRowIndex, colWidths, rect, table, nextRowOpt){
        let cell = null;
        let newpage = 1;
        let pageIndex = null;
        let rowIndex = null;
        let rows = table.getRows();
        let type = nextRowOpt.type;
        let pageRect = nextRowOpt.pageRect;

        for(var i = 0; i < colWidths.length; i++){
            cell = row.getCells(i);

            cell.__rowIndex = tableRowIndex;
            cell.__colIndex = i;

            if(!cell) continue;

            if(cell.__boundRect){
                delete cell.__boundRect;
            }
            
            if(nextRowOpt.index == tableRowIndex){
                pageIndex = nextRowOpt.pageIndex;
                rowIndex = nextRowOpt.rowIndex;
                rect.height = nextRowOpt.height;
                rect.pageHeight = nextRowOpt.pageRect.height;
            }

            //不可见单元格(被合并的单元格)
            if(cell.style.display == "none"){
                formatSpanCellLastRow.call(this, 
                    row, tableRowIndex, i, colWidths, table, nextRowOpt);
                continue;
            }

            if(isColSpanCell(cell)){
                rect.width = sumColWidth(colWidths, i, i + cell.colspan);
            }else{
                rect.width = colWidths[i];
            }

            if(cell.__pageList){
                delete cell.__pageList;
            }

            while(newpage > 0){
                if(cell.__page){
                   //对已排版的单元格按指定包围盒大小进行外部分割                
                    newpage = splitPageForCell.call(this, cell, rect, rowIndex, pageIndex, newpage, type);
                }else{
                    //对未排版的单元格按指定包围盒大小进行内部排版和外部分割
                    newpage = pagingCell.call(this, cell, rect, rowIndex, pageIndex, type);
                }

                //如果上方存在单元格，则修改当前单元格的上边距
                if(tableRowIndex > 0){
                    setElementBoundRect(cell, rowIndex, pageIndex, (cellRect)=>{
                        if(!cellRect) return;
                        cellRect.top += getCellsHeight.call(table, rows, tableRowIndex, i, rowIndex, pageIndex)
                        if(nextRowOpt.head.apply[pageIndex]){
                            cellRect.top += nextRowOpt.head.apply[pageIndex];
                        }
                    });
                }

                if(newpage > 0){
                    if(row.__index == cell.__rowIndex){
                        //按照页码、行号分组计算单元格所在行包围盒
                        mergeTableElement(row, cell.__boundRect, null, null, (eleRect, pIndex, element)=>{
                            return pIndex != pageIndex;
                        });
                    }

                    rowIndex = 1;
                    pageIndex++;

                    rect.height = pageRect.height;

                    //当前行非表头、表头高度大于0且表头不在当前页
                    if(!row.head && nextRowOpt.head.height > 0 && 
                        nextRowOpt.head.pageRange.length == 1 &&
                        nextRowOpt.head.pageRange.indexOf(pageIndex) < 0){
                        nextRowOpt.head.apply[pageIndex] = nextRowOpt.head.height; 
                        nextRowOpt.minusHeadHeight = nextRowOpt.head.height;
                        rect.height -= nextRowOpt.head.height;
                    }
                }else{
                    break;
                }
            }

            newpage = 1;

            if(!isRowSpanCell(cell)) {
                //按照页码、行号分组计算单元格所在行包围盒
                mergeTableElement(row, cell.__boundRect, (rowRect, cellRect)=>{
                    rowRect.top = cellRect.top;
                    rowRect.width = nextRowOpt.rowWidth;
                });
            }

            mergeTableElement(nextRowOpt.vRow, cell.__boundRect, (rowRect, cellRect, opt)=>{
                if(!nextRowOpt.minPageIndex){
                    nextRowOpt.minPageIndex = opt.pageIndex;
                }else if(nextRowOpt.minPageIndex > opt.pageIndex){
                    nextRowOpt.minPageIndex = opt.pageIndex;
                }

                rowRect.top = cellRect.top;
                rowRect.width = nextRowOpt.rowWidth;
            });
        }
    }

    /**
     * 对合并单元格最后一行和内部单元格重新结算包围盒
     * @param {*} row 
     * @param {*} tableRowIndex 
     * @param {*} colWidths 
     * @param {*} table 
     * @param {*} nextRowOpt 
     * @returns 
     */
    var formatSpanCellLastRow = function(row, tableRowIndex, tableColIndex, colWidths, table, nextRowOpt){
        let spanCell = getSpanCell(table, tableRowIndex, tableColIndex);
        if(!spanCell) return;

        let rows = table.getRows();
        let type = nextRowOpt.type;
        let pageRect = nextRowOpt.pageRect;

        let endRowIndex = spanCell.getRowIndex() + spanCell.getRowspan() - 1;

        //合并单元格的范围内最后一行(合并单元格本身不在此行)
        if(endRowIndex == tableRowIndex && spanCell.getRowIndex() != tableRowIndex){
            let cell = spanCell.getRef();
            let key = spanCell.getRowIndex() + "-" + spanCell.getColIndex();

            //重新对单元格进行排版，只排一次
            if(!nextRowOpt.formatSpanCellInfo.isRun[key] && spanCell.getColspan() < colWidths.length){
                splitCellByBoundRect.call(this, cell, pageRect, pageIndex, type, (opt)=>{
                    if(!opt.isChange) return;
                    
                    //当合并单元格高度变化时，带动表格在变化页最后一个表格行中的所有单元格同步变化
                    let rows = table.getRows();

                    let r = null;
                    let belongRow = null;
                    let belongRowIndex = null;

                    //找到表格在指定页的最后一个表格行
                    for(let i = cell.__rowIndex; i < rows.length; i++){
                        r = rows[i];

                        if(belongRow && (!r.__boundRect || !r.__boundRect[opt.pageIndex])){
                            break;
                        }else if(r.__boundRect && r.__boundRect[opt.pageIndex]){
                            belongRow = r;
                            belongRowIndex = i;
                        }
                    }

                    if(!belongRow || !belongRow.__boundRect) {
                        return;
                    }

                    //表明该合并单元格在第一列，此时该行还没有计算包围盒，故延后处理
                    if(belongRow.__index != endRowIndex){
                        return;
                    }

                    let cellRect = cell.__boundRect[opt.pageIndex][opt.index];
                    let rowRect = belongRow.__boundRect[opt.pageIndex][opt.index];

                    //1.如果变化页最后一行的包围盒还未计算
                    //2.如果变化页最后一行已经在之前的排版中得出行高，除非小于变化后的高度才进行高度同步
                    if(!rowRect || rowRect.height < cellRect.top + cellRect.height - rowRect.top){
                        rowRect.height = cellRect.top + cellRect.height - rowRect.top;
                        resizeCellInRow(table, colWidths, belongRow, belongRowIndex, opt.pageIndex);
                    }
                });

                nextRowOpt.formatSpanCellInfo.isRun[key] = true;
            }

            mergeTableElement(row, cell.__boundRect, (rowRect, cellRect, opt)=>{
                let rowHeight = sumRowHeight(
                    rows, 
                    spanCell.getRowIndex(), 
                    tableRowIndex, 
                    opt.index, 
                    opt.pageIndex
                ); 

                //当前单元格未到最后一列
                if(spanCell.getColIndex() + spanCell.getColspan() < colWidths.length){
                    if(rowRect.height < cellRect.height - rowHeight || opt.init){
                        rowRect.height = cellRect.height - rowHeight;
                    }
                }
                //当前行所有单元格被合并成一个单元格
                else if(spanCell.getColIndex() == 0 && 
                    spanCell.getColIndex() + spanCell.getColspan() == colWidths.length){
                    rowRect.height = 0;
                }else if(rowRect.height < cellRect.height - rowHeight){
                    rowRect.height = cellRect.height - rowHeight;
                }

                //表格行左边距一定是0
                rowRect.left = 0;
                rowRect.top = cellRect.top + rowHeight;
                rowRect.width = nextRowOpt.rowWidth;
            }, 2, (eleRect, pIndex, element)=>{
                return pIndex < pageIndex ||
                    (nextRowOpt.minPageIndex && nextRowOpt.minPageIndex > pIndex);
            });
        }
    }

    /**
     * 根据表格行包围盒，重新调整内部单元格的包围盒
     * @param {*} table 
     * @param {*} colWidths 
     * @param {*} row 
     * @param {*} rowIndex 
     * @param {*} pageIndex 
     */
    var resizeCellInRow = function(table, colWidths, row, rowIndex, pageIndex){
        var cell = null;
        var colWidth = 0;

        for(var i = 0; i < colWidths.length; i++){
            cell = row.getCells(i);
            if(!cell) continue;

            if(cell.style.display == "none"){
                cell = getSpanCell(table, rowIndex, i);
                if(!cell) continue;

                //和合并单元格处于同一行
                if(cell.getRowIndex() == rowIndex){
                    mergeTableElement(cell.getRef(), row.__boundRect, (cellRect)=>{
                        cellRect.width += colWidths[i];
                    }, 2); 
                }else if(cell.getColIndex() == i){
                    //和合并单元格处于同一列
                    //合并单元格最后一行标志
                    var lastSpanRow = cell.getRowIndex() + cell.getRowspan() - 1 == rowIndex;
                    mergeTableElement(cell.getRef(), row.__boundRect, (cellRect, rowRect, opt)=>{
                        cellRect.left = colWidth;
                        cellRect.width = sumColWidth(
                            colWidths, 
                            cell.getColIndex(), 
                            cell.getColIndex() + 
                            cell.getColspan()
                        );
                        
                        if(lastSpanRow && pageIndex >= opt.pageIndex){
                            delete cellRect.spanRowHeight;
                        }else{
                            cellRect.spanRowHeight = rowRect.top + rowRect.height - cellRect.top;
                        }

                        if(!lastSpanRow || cellRect.top + cellRect.height < rowRect.top + rowRect.height){
                            cellRect.height = rowRect.top + rowRect.height - cellRect.top;
                        }else if(lastSpanRow && pageIndex >= opt.pageIndex){
                            rowRect.height = cellRect.top + cellRect.height - rowRect.top;
                        }
                    }, 2); 
                }

                setCellAlign(cell.getRef());
            }else{
                mergeTableElement(cell, row.__boundRect, (cellRect)=>{
                    cellRect.left = colWidth;
                    cellRect.width = colWidths[i];
                }); 

                setCellAlign(cell);

            }
            colWidth += colWidths[i];
        }
    }

    /**
     * 对表格内所有单元格进行内部排版
     * @param {*} table 
     * @param {*} colWidths 
     * @param {*} type
     * @param {*} opt
     */
    var cellsFormat = function(table, colWidths, type, opt){
        //当前行
        var row = null;
        //当前行单元格集合
        var cells = null;
        //当前单元格
        var cell = null;
        
        //表格行
        var rows = table.getRows();

        //列宽
        var colWidth = 0;
        var padding = null;

        //将所有单元格内部进行排版
        for(var i = 0; i < rows.length; i++){
            row = rows[i];
            cells = row.getCells();

            for(var j = 0; j < cells.length; j++){
                cell = cells[j];
                if(!cell || cell.style.display == "none") continue;

                //在某个单元格内部编辑时，其他单元格不需要重新排版
                //且这个单元格之前内容未改变
                if(matchCellContentEdit(opt, table) && 
                   isNotContentEditOfCell(i, j, opt) && 
                   !cell.__contentMutate) continue;

                if(isSpanCell(cell)){
                    //合并宽度
                    colWidth = sumColWidth(colWidths, j, j + cell.colspan);
                }else{
                    colWidth = colWidths[j];
                }

                if(cell.style && cell.style.padding){
                    padding = converter.parsePoM(cell.style.padding);
                    if(colWidth < padding.left + padding.right){
                        colWidth = padding.left + padding.right + 2;
                        colWidths.splice(j, 1, colWidth);
                    }
                }

                //单元格内部排版
                tableCellFormat(
                    cell, 
                    {
                        left: 0,
                        top: 0,
                        width: colWidth,
                        height: 10000000
                    }, 
                    type,
                    opt
                );

                delete cell.__contentMutate;
            }
        }
    }

    /**
     * 判断是否不是内容编辑的单元格
     * @param {*} tableRowIndex 
     * @param {*} tableColIndex 
     * @param {*} opt 
     */
    var isNotContentEditOfCell = function(tableRowIndex, tableColIndex, opt){
        if(!opt || !opt.cellContentEdit) return false;
        if(opt.cellContentEdit.tableRowIndex == null || opt.cellContentEdit.tableColIndex == null){
            return false;
        }

        return opt.cellContentEdit.tableRowIndex != tableRowIndex || 
            opt.cellContentEdit.tableColIndex != tableColIndex;
    }

    /**
     * 累加列宽
     * @param {*} colWidths 列宽集合
     * @param {*} beginIndex 起始列序号
     * @param {*} endIndex 终止列序号
     * @returns 
     */
    var sumColWidth = function(colWidths, beginIndex, endIndex){
        var width = 0;
        for(var i = beginIndex; i < endIndex; i++){
            width += colWidths[i];
        }
        return width;
    }

    /**
     * 累加行高
     * @param {*} rows 行集合
     * @param {*} beginIndex 起始行序号 
     * @param {*} endIndex 终止行序号
     * @param {*} index 页面行号
     * @param {*} pageIndex 页码
     */
    var sumRowHeight = function(rows, beginIndex, endIndex, index, pageIndex){
        var row = null;
        var rect = null;
        var height = 0;

        for(var i = beginIndex; i < endIndex; i++){
            row = rows[i];
            rect = getElementBoundRect(row, index, pageIndex);
            if(!rect) continue;
            height += rect.height;
        }

        return height;
    }
    
    /**
     * 分析合并单元格
     * @param {*} table 
     */
    var parseSpanCell = function(table){
        table.__spanCells = [];

        var rows = table.getRows();
        var cell = null;
        var cells = null;

        for(var i = 0; i < rows.length; i++){
            cells = rows[i].getCells();

            for(var j = 0; j < cells.length; j++){
                cell = cells[j];

                if(getSpanCell(table, i, j)){
                    cell.style.display = "none";
                    continue;
                }

                if((!cell.rowspan || cell.rowspan == 1) && 
                   (!cell.colspan || cell.colspan == 1)) continue;

                //防止跨行数和跨列数越界
                if(cell.rowspan > rows.length - i){
                    cell.rowspan = rows.length - i;
                }else if(cell.rowspan < 1){
                    cell.rowspan = 1;
                }

                if(cell.colspan > cells.length - j){
                    cell.colspan = cells.length - j;
                }else if(cell.colspan < 1){
                    cell.colspan = 1;
                }

                table.__spanCells.push(table.createSpanCellProxy(cell, i, j));
            }
        }
    }

    /**
     * 是否是合并单元格
     * @param {*} cell 
     */
    var isSpanCell = function(cell){
        return (cell.rowspan && cell.rowspan > 1) ||
               (cell.colspan && cell.colspan > 1); 
    }

    /**
     * 是否是跨行单元格
     * @param {*} cell 
     * @returns 
     */
    var isRowSpanCell = function(cell){
        return cell.rowspan && cell.rowspan > 1; 
    }

    /**
     * 是否是跨列单元格
     * @param {*} cell 
     * @returns 
     */
    var isColSpanCell = function(cell){
        return cell.colspan && cell.colspan > 1; 
    }

    /**
     * 获取合并单元格
     * @param {*} table 表格元素
     * @param {*} rowIndex 表格行序号
     * @param {*} cellIndex 表格列序号
     * @returns 
     */
    this.getSpanCell = function(table, rowIndex, cellIndex){
        return getSpanCell.call(this, table, rowIndex, cellIndex);
    }

    /**
     * 获取合并单元格
     * @param {*} table 表格元素
     * @param {*} rowIndex 表格行序号
     * @param {*} cellIndex 表格列序号
     * @returns 
     */
    var getSpanCell = function(table, rowIndex, cellIndex){
        if(!table.__spanCells) return null;

        var spanCell = null;

        for(var i = 0; i < table.__spanCells.length; i++){
            spanCell = table.__spanCells[i];
            
            if(spanCell.include(rowIndex, cellIndex)){
                return spanCell;
            }
        }

        return null;
    }

    /**
     * 获取指定行列号所在合并单元格下所有被合并的单元格
     * @param {*} table 
     * @param {*} rowIndex 
     * @param {*} colIndex 
     */
    var getSpanCellRelCells = function(table, rowIndex, colIndex){
        if(!table.__spanCells) return null;

        var spanCell = null;
        var cells = [];

        for(var i = 0; i < table.__spanCells.length; i++){
            spanCell = table.__spanCells[i];
            if(spanCell.include(rowIndex, colIndex)){
                break;
            }
        }

        var rowBeginIndex = spanCell.getRowIndex();
        var rowEndIndex = rowBeginIndex + spanCell.getRowspan();
        var colBeginIndex = spanCell.getColIndex();
        var colEndIndex = colBeginIndex + spanCell.getColspan();

        var row = null;
        var cell = null;

        for(var i = rowBeginIndex; i < rowEndIndex; i++){
            row = table.getRows(i);

            for(var j = colBeginIndex; j < colEndIndex; j++){
                cell = row.getCells(j);
                if(i == rowBeginIndex && j == colBeginIndex) continue;

                cells.push(cell);
            }
        }

        return cells;
    }

    /**
     * 按指定包围盒进行合并
     * @param {*} element 表格元素
     * @param {*} boundRect 用于合并的包围盒
     * @param {*} callback 回调方法
     * @param {*} mode 1选择最大高度(默认) 2高度自定义
     * @param {*} filter 过滤方法
     */
    var mergeTableElement = function(element, boundRect, callback, mode, filter){
        var init = false;

        elementBoundRectForEach({__boundRect: boundRect}, (eleRect, pIndex, rIndex)=>{
            if(filter && filter(eleRect, pIndex, element)) return;

            if(!element.__boundRect){
                element.__boundRect = [];
            }

            if(!element.__boundRect[pIndex]){
                element.__boundRect[pIndex] = [];
            }

            if(!element.__boundRect[pIndex][rIndex]){
                element.__boundRect[pIndex][rIndex] = { ...eleRect };
                init = true;
            }else if(!mode || mode == 1){
                if(element.__boundRect[pIndex][rIndex].height < eleRect.height){
                    element.__boundRect[pIndex][rIndex].height = eleRect.height;
                }
            }

            if(callback){
                callback(element.__boundRect[pIndex][rIndex], eleRect, {
                    init: init,
                    pageIndex: pIndex,
                    index: rIndex
                });
            }
        })
    }

    /**
     * 获取当前列单元格累加高度
     * @param {*} rows 表格行元素集合
     * @param {*} endRowIndex 截止表格行序号
     * @param {*} colIndex 表格列序号
     * @param {*} rowIndex 页面行号
     * @param {*} pageIndex 页码
     * @returns 
     */
    var getCellsHeight = function(rows, endRowIndex, colIndex, rowIndex, pageIndex){
        var height = 0;
        var row = null;
        var cell = null;
        var boundRect = null;

        for(var i = endRowIndex - 1; i > -1; i--){
            row = rows[i];
            cell = row.getCells(colIndex);
            if(!cell) continue;
            
            if(cell.style.display == "none") {
                var spanCell = getSpanCell(this, i, colIndex);
                if(!spanCell) continue;

                boundRect = getElementBoundRect(spanCell.getRef(), rowIndex, pageIndex);
                if(!boundRect) break;
                
                i -= spanCell.getRowspan() - 1;
            }else{
                boundRect = getElementBoundRect(cell, rowIndex, pageIndex);
                if(!boundRect) break;
            }

            height += boundRect.height;
        }

        return height;
    }

    /**
     * 对表格单元格内部进行排版
     * @param {*} cell 单元格元素
     * @param {*} pageRect 单元格内部排版页面包围盒
     * @param {*} type 页面布局类型：body(页体,默认) head(页眉) foot(页脚) 
     * @param {*} opt 可选项
     */
    var tableCellFormat = function(cell, pageRect, type, opt){
        if(cell.__page){
            delete cell.__page;
        }

        var paragraphs = {body: []};
        var align = parseCellAlign(cell);
        
        parseParagraph(cell.children, 1, paragraphs.body);

        if(align){
            for(var i in paragraphs.body){
                //在修改时，会给修改的元素设置变异标记，判断完成后要清除
                if(cell.__mutate){
                    paragraphs.body[i].style.textAlign = align.textAlign;
                    delete cell.__mutate;
                }else if(paragraphs.body[i].__mutate){
                    delete paragraphs.body[i].__mutate;
                }
            }
        }

        var opt = {
            paragraphs: paragraphs,
            traceDisplay: setting.traceDisplay
        };

        if(cell.style.padding){
            opt.style = {
                padding: cell.style.padding
            }
        }

        var page = new sPage(pageIndex, opt);
        var render = new sLayoutEngine(
            painter.createPainter(), 
            page, 
            ratio, {
                pageRect: pageRect,
                setting: setting
            }
        );
        var child = null;
        var option = {...opt};

        for(var i = 0; i < cell.children.length; i++){
            child = cell.children[i];

            option.prevElement = cell.children[i - 1];
            option.nextElement = cell.children[i + 1];

            linkElement(child, cell.children[i + 1]);

            if(child.__boundRect){
                delete child.__boundRect;
            }

            if(child.__texts){
                delete child.__texts;
            }

            if(child.__rows){
                delete child.__rows;
            }

            generateCellInnerPage.call(
                render, 
                child,
                option
            );

            unlinkElement(child);
        }

        cell.__page = page;
    }

    /**
     * 生成单元格内部分页
     * @param {*} element 单元格内部子元素
     * @returns 
     */
    var generateCellInnerPage = function(element, opt){
        var rect = this.getPage().getBoundRect("body", true);
        var newpage = 0;
        
        try{
            switch(element._sType){
                case "sText":
                    newpage = this.textFormat(element, rect, "body");
                    break;
                case "sParagraph":
                    newpage = this.paragraphFormat(element, rect, "body");
                    break;
                case "sBreakline":
                    newpage = this.breaklineFormat(element, "body");
                    break;
                case "sLayer":
                    newpage = this.layerFormat(element, "body");
                    break;
                case "sInputBegin":
                case "sInputEnd":
                    newpage = this.inputAreaFormat(element, rect, "body", opt);
                    break;
                case "sTable":
                    newpage = this.tableFormat(element, rect, "body", opt);
                    break;
            }
        }catch(e){
            console.error(e);
        }

        return newpage;
    }

    /**
     * 对单元格内部单页进行分页
     * @param {*} cell 单元格元素
     * @param {*} pageRect 分页包围盒
     * @param {*} index 行码
     * @param {*} pageIndex 页码
     * @param {*} newpage 上一次分页状态值
     * @param {*} type 页面布局类型：body(页体,默认) head(页眉) foot(页脚) 
     * @returns 0 无需新增页 1需新增页 2当前包围盒无法对单元格进行分割，需新增页
     */
    var splitPageForCell = function(cell, pageRect, index, pageIndex, newpage, type){
        var pageList = cell.__pageList;
        
        if(!pageList || pageList.getPageSize() == 0){
            pageList = new sPageList();
            pageList.setOwnerElement(cell);
            pageList.insertPage({
                startIndex: pageIndex,
                paragraphs: cell.__page.getParagraphs(),
                style: {
                    padding: cell.style.padding
                },
                ignoreHeadFoot: true,
                traceDisplay: setting.traceDisplay
            });
            cell.__pageList = pageList;
            cell.__boundRect = [];
            cell.__boundRectTotalHeight = 0;
        }else{
            pageList.insertPage({
                paragraphs: cell.__page.getParagraphs(),
                style: {
                    padding: cell.style.padding
                },
                ignoreHeadFoot: true
            });
        }

        pageList.getLastPage().setBoundRect({
            left: pageRect.left,
            top: pageRect.top,
            width: pageRect.width,
            height: pageRect.height
        });

        var lastPage = pageList.getLastPage();
        var actualRect = lastPage.getBoundRect("body", true);  
        var outParam = {
            pageHeight: pageRect.pageHeight,
            newpage: newpage
        };

        //填充页
        fillCellPage.call(this, cell, lastPage, actualRect, outParam);

        pageIndex = cell.__pageList.getLastPage().getIndex();

        var newpage = outParam.newpage;
        var remainHeight = outParam.remainHeight;
        var height = 0;
        var padding = lastPage.getPadding();

        //需产生新页，将单元格高度设置为当前分页包围盒高度
        if(newpage == 1){
            height = lastPage.getBoundRect("body", true).height;
            //pageRect.height;
        }else if(newpage == 0){
            //不需产生新页，将单元格高度设置为最后一页包围盒实际大小
            height = lastPage.getBoundRect("body").height + padding.top + padding.bottom;

            //指定行高
            if(pageRect.rowHeight && height + cell.__boundRectTotalHeight < pageRect.rowHeight){
                if(pageRect.height > pageRect.rowHeight - cell.__boundRectTotalHeight){
                    height = pageRect.rowHeight - cell.__boundRectTotalHeight;
                    remainHeight = pageRect.height - height;
                }else{
                    height = pageRect.height;
                    remainHeight = 0;
                    newpage = 1;
                }
            }
        }else{
            //需产生新页，但当前页面无法分隔单元格，则移除当前页并返回
            cell.__pageList.removeLastPage();
            return newpage;
        }

        //单元格最小高度
        var minHeight = parseFloat(cell.style.minHeight);

        if(minHeight > this.getPage().getBoundRect(type, true).height){
            minHeight = this.getPage().getBoundRect(type, true).height;
        }

        //如果高度小于单元格最小高度
        if(height < minHeight && cell.__boundRectTotalHeight + height < minHeight){
            height = minHeight - cell.__boundRectTotalHeight;
            
            //如果高度溢出页面，则移到下一页
            if(height > pageRect.height){
                cell.__pageList.removeLastPage();
                delete cell.__end;
                return 2;
            }else{
                remainHeight = pageRect.height - height;
            }
        }

        cell.__boundRect[pageIndex] = [];
        cell.__boundRect[pageIndex][index] = {
            left: 0,
            top: 0,
            width: pageRect.width,
            height: height
        };

        if(!cell.__boundRectTotalHeight){
            cell.__boundRectTotalHeight = 0;
        }

        cell.__boundRectTotalHeight += height;

        pageRect.height = remainHeight;

        if(newpage == 0){
            delete cell.__end;
        }

        return newpage;
    }

    /**
     * 获取单元格内部段落属性
     * @param {*} cell 
     * @returns 
     */
    var getParagraphForCell = function(cell){
        var paragraphs = {body: []};
        var align = parseCellAlign(cell);
        
        parseParagraph(cell.children, 1, paragraphs.body);

        if(align){
            for(var i in paragraphs.body){
                paragraphs.body[i].style.textAlign = align.textAlign;
            }
        }

        return paragraphs;
    }

    /**
     * 单元格分页
     * @param {*} cell 单元格
     * @param {*} pageRect 包围盒
     * @param {*} index 页面行号
     * @param {*} pageIndex 页码
     * @param {*} type 页面布局类型：body(页体,默认) head(页眉) foot(页脚) 
     */
    var pagingCell = function(cell, pageRect, index, pageIndex, type){
        var pageList = cell.__pageList;
        
        if(!pageList || pageList.getPageSize() == 0){
            pageList = new sPageList();
            pageList.insertPage({
                paragraphs: getParagraphForCell(cell),
                startIndex: pageIndex,
                style: {
                    padding: cell.style.padding
                }
            });

            cell.__pageList = pageList;
            cell.__boundRect = [];
            cell.__boundRectTotalHeight = 0;
        }else{
            pageList.insertPage({
                paragraphs: pageList.getLastPage().getParagraphs(),
                style: {
                    padding: cell.style.padding
                }
            });
        }

        var render = new sLayoutEngine(
            painter.createPainter(),
            pageList.getLastPage(), 
            ratio, 
            { 
                pageRect: pageRect,
                setting: setting
            }
        );

        var newpage = 0;

        if(cell.__end == null){
            cell.__end = 0;
        }

        for(var i = cell.__end; i < cell.children.length; i++){
            newpage = generateCellInnerPage.call(
                render, 
                cell.children[i]
            );

            cell.__end = i;

            if(newpage > 0){
                break;
            }
        }

        if(cell.__end == cell.children.length){
            delete cell.__end;
        }

        if(!cell.__boundRect[pageIndex]){
            cell.__boundRect[pageIndex] = [];
        }

        var page = pageList.getLastPage();
        var height = page.getBoundRect("body").height;
        var padding = page.getPadding();

        height += padding.top + padding.bottom;

        cell.__boundRect[pageIndex][index] = {
            left: 0,
            top: 0,
            width: pageRect.width,
            height: height
        };

        cell.__boundRectTotalHeight += height;

        return newpage;
    }

    /**
     * 填充页
     * @param {*} cell 单元格
     * @param {*} fillPage 填充页
     * @param {*} actualRect 填充包围盒
     * @param {*} outParam 出参
     * @returns 
     */
    var fillCellPage = function(cell, fillPage, actualRect, outParam){
        var newpage = 0;
        var height = 0;
        var rowHeight = 0;
        var remainHeight = actualRect.height;

        cell.__page.forEach((row, rowIndex, type)=>{
            if(type != "body") return true;

            if(cell.__table){
                newpage = reflowTable(cell.__table, actualRect, fillPage);
                if(newpage > 0){
                    remainHeight = 0;
                    cell.__end = rowIndex - 1;
                    return true;
                }else{
                    delete cell.__table;
                    rowHeight = fillPage.getLastRow("body").getBoundRect().height;
                    remainHeight -= rowHeight;
                    height += rowHeight;
                    return false;
                }
            }

            rowHeight = row.getBoundRect("body").height;
            height += rowHeight;

            if(height <= actualRect.height){
                //对表格重新排版
                if(row.getElementList()[0]._sType == "sTable"){
                    let table = row.getElementList()[0];
                    delete table.__pageRange;

                    let pageRect = {...actualRect, height: outParam.pageHeight};
                    reflowTable(table, actualRect, fillPage, pageRect);
                    // fillPage.updateRow("body", row, {needInsert: false});
                }else{
                    fillPage.insertRow("body", row);
                }

                remainHeight -= rowHeight;
                cell.__end = rowIndex;
            }else{
                //如果当前行包含表格且超出区域，则对表格进行拆分
                if(row.getElementList()[0]._sType == "sTable"){
                    let table = row.getElementList()[0];
                    delete table.__pageRange;

                    let pageRect = {...actualRect, height: outParam.pageHeight};
                    newpage = reflowTable(table, actualRect, fillPage, pageRect);

                    remainHeight = 0;

                    cell.__end = newpage > 0 ? rowIndex - 1 : rowIndex;
                    cell.__table = table;

                    return true;
                }

                //上一次分页状态表明单行高度超出页面高度，则进行裁剪
                if(outParam.newpage == 2 && 
                   remainHeight == actualRect.height){
                    fillPage.insertRow("body", row);

                    row.setBoundRect({
                        height: actualRect.height
                    });

                    remainHeight = 0;
                    cell.__end = rowIndex;

                    newpage = 1;
                }else{
                    newpage = remainHeight < actualRect.height ? 1 : 2;
                    cell.__end = rowIndex - 1;
                }

                return true;
            }
        }, cell.__end ? cell.__end : 0);

        outParam.newpage = newpage;
        outParam.remainHeight = remainHeight;
    }

    /**
     * 重新排版表格
     * @param {*} table 
     * @param {*} initRect
     * @param {*} pageRect 
     * @param {*} page 
     * @returns 
     */
    var reflowTable = function(table, initRect, page, pageRect){
        let render = new sLayoutEngine(
            painter.createPainter(),
            page, 
            ratio, 
            { 
                pageRect: initRect,
                setting: setting
            }
        );

        return render.tableFormat(table, initRect, "body", {pageRect: pageRect});
    }

    /**
     * 解析单元格布局
     * @param {*} cell 
     * @returns 
     */
    var parseCellAlign = function(cell){
        if(cell.style.align){
            var align = cell.style.align.replace(/([LCR])/g, ",$1");
            var arr = align.split(",");
            
            if(arr.length > 1){
                return {
                    verticalAlign: arr[0],
                    textAlign: arr[1].toLowerCase()
                }
            }
        }

        return null;
    }

    /**
     * 设置单元格纵向排列
     * @param {*} cell 
     */
    var setCellAlign  = function(cell){
        if(cell.style.align && cell.__pageList && 
            cell.__pageList.getPageSize() == 1){
                
            var align = parseCellAlign(cell);

            if(isSpanCell(cell)){
                var pageIndex = cell.__pageList.getLastPage().getIndex();

                cell.__boundRectTotalHeight = 0;
                elementBoundRectForEach(cell, (cellRect, pIndex)=>{
                    if(pageIndex != pIndex) return;
                    cell.__boundRectTotalHeight += cellRect.height;
                });
            }else{
                var pageIndex = cell.__pageList.getFirstPage().getIndex();
                var rect = getElementBoundRect(cell, -1, pageIndex);
                cell.__boundRectTotalHeight = rect.height;
            }

            if(cell.style && cell.style.padding){
                var padding = converter.parsePoM(cell.style.padding);
                cell.__boundRectTotalHeight -= (padding.top + padding.bottom);
            }

            var page = cell.__pageList.getFirstPage();
            var boundRect = page.getBoundRect("body");

            if(align.verticalAlign == "top"){
                offsetHeight = 0;
            }else if(align.verticalAlign == "middle"){
                offsetHeight = (cell.__boundRectTotalHeight - boundRect.height) / 2;
            }else if(align.verticalAlign == "bottom"){
                offsetHeight = cell.__boundRectTotalHeight - boundRect.height;
            }

            //单元格内部垂直偏移高度，用于居上、居中、居下显示
            cell.__boundRect.verticalOffsetHeight = offsetHeight;
        };
    }

    /**
     * 根据单元格现有的包围盒进行重新分页
     * @param {*} cell 单元格
     * @param {*} pageRect 页面包围盒
     * @param {*} pageIndex 启用页面包围盒的页码
     * @param {*} type 页面布局类型：body(页体,默认) head(页眉) foot(页脚) 
     * @param {*} callback 回调函数
     */
    var splitCellByBoundRect = function(cell, pageRect, pageIndex, type, callback) {
        //if(cell.__boundRect.length < 3) return;

        var length = cell.__boundRect.length - 1 - 
            cell.__pageList.getNullPageCount() - cell.__pageList.getPageSize();
        
        if(length > 0){
            for(var i = 0; i < length; i++) {
                page = cell.__pageList.insertPage({
                    style: cell.style.padding
                });
                page.setBoundRect({
                    left: pageRect.left,
                    top: pageRect.top,
                    width: pageRect.width,
                    height: pageRect.height
                });
            };
        }

        var innerRect = null;
        var cellRect = null;
        var page = null;
        var row = null;
        var height = 0;

        elementBoundRectForEach(cell, (boundRect, pIndex, rIndex)=>{
            page = cell.__pageList.getPage(pIndex);
            if(!page) return;

            cellRect = pageIndex == pIndex ? { ...pageRect} : boundRect;

            if(cellRect.spanRowHeight){
                boundRect.height = cellRect.spanRowHeight;
            } 

            while(true){
                innerRect = page.getBoundRect("body");

                if(innerRect.height > cellRect.height && 
                   cell.__pageList.getPageSize() > pIndex){

                    row = page.removeLastRow(type);
                    cell.__pageList.getPage(pIndex + 1).insertToFirst(type, row);
                }else{
                    height = cell.__pageList.getPage(pIndex).getBoundRect("body").height;
                    if(boundRect.height < height){
                        boundRect.height = height;
                        if(callback){
                            callback({
                                isChange: true,
                                pageIndex: pIndex,
                                index: rIndex
                            })
                        }
                    }

                    break;
                }
            }
        });
    }

    /**
     * 元素包围盒遍历操作
     * @param {*} element 
     * @param {*} callback 
     */
    var elementBoundRectForEach = function(element, callback){
        if(element.__boundRect instanceof Array){
            for(var i in element.__boundRect){
                for(var j in element.__boundRect[i]){
                    callback(element.__boundRect[i][j], 
                        parseInt(i), parseInt(j), element.__boundRect.length - 1);
                }
            }
        }else{
            callback(element.__boundRect, 1, 1, 1);
        }
    }

    /**
     * 设置元素包围盒
     * @param {*} element 
     * @param {*} callback 
     */
    var setElementBoundRect = function(element, index, pageIndex, callback){
        var rect = null;

        if(element.__boundRect instanceof Array){
            if(element.__boundRect[pageIndex]){
                rect = element.__boundRect[pageIndex][index];
            }
        }else{
            rect = element.__boundRect;
        }
        
        callback(rect);
    }

    /**
     * 获取元素包围盒
     * @param {*} element 
     * @param {*} index 
     * @param {*} pageIndex 
     * @param {*} callback
     * @returns 
     */
    var getElementBoundRect = function(element, index, pageIndex, callback){
        var rect = null;

        if(element.__boundRect instanceof Array){
            if(index == -1){
                for(var i in element.__boundRect[pageIndex]){
                    if(!element.__boundRect[pageIndex][i]) continue;
                    rect = element.__boundRect[pageIndex][i];
                    if(callback){
                        callback(rect, parseInt(i));
                        return;
                    }
                }
            }else if(index && element.__boundRect[pageIndex]){
                rect = element.__boundRect[pageIndex][index];
            }else{
                rect = element.__boundRect[pageIndex];    
            }
        }else{
            rect = element.__boundRect;
        }
        
        if(callback){
            callback(rect);
        }else{
            return rect;
        }
    }

    /**
     * 解析段落
     * @param {*} elements 
     * @param {*} index 
     * @param {*} paragraphs 
     */
    var parseParagraph = function(elements, index, paragraphs){
        for(var i in elements){
            var element = elements[i];
            if(!element._sType) continue;

            element.__paragraphIndex = index;

            if(element._sType == "sParagraph"){
                paragraphs[index] = element;
                index++;
            }

            if(element.children && element._sType != "sLayer"){
                parseParagraph(element.children, ++index, paragraphs);
            }
        }
    }

    /**
     * rang偏移量属性名称集合
     */
    var rangeOffsetProps = [
        "pageIndex",
        "rowIndex",
        "elementIndex",
        "contentIndex",
        "next"
    ];

    /**
     * 表格rang偏移量属性名称集合
     */
    var tableRangeOffsetProps = [
        "tableRowIndex",
        "tableColIndex"
    ]

    /**
     * range偏移量属性名称集合扩展
     */
    var rangeOffsetPropsExt = tableRangeOffsetProps.concat(rangeOffsetProps);

    /**
     * 触发选择
     * @param {*} sEvt 
     */
    var doSelection = function(sEvt){
        if(!sEvt || !sEvt.selection) return;

        var range = sEvt.selection.getRangeAt();

        if(range.__start == 1){
            range.__position = sEvt.target.position;
            range.__startContainer = sEvt.target.ref;
            range.__startOffset = ost.extractOffset(sEvt.target);

            range.startContainer = range.__startContainer;
            range.startOffset = range.__startOffset;

        }else if(range.__start == 2){
            if(range.__position != sEvt.target.position) return;

            var endOffset = {};
            endOffset = ost.extractOffset(sEvt.target);

            if(canExchange(range.__startOffset, endOffset)){
                range.startContainer = sEvt.target.ref;
                range.startOffset = endOffset;
        
                range.endContainer = range.__startContainer;
                range.endOffset = range.__startOffset;
            }else{
                range.startContainer = range.__startContainer;
                range.startOffset = range.__startOffset;

                range.endContainer = sEvt.target.ref;
                range.endOffset = endOffset;
            }
        }else{
            delete range.__start;
            range.reset();
        }
    }

    /**
     * 判断range的起始和结束向量是否相等
     * @param {*} range 
     * @returns 
     */
    var equalsRangeOffset = function(range){
        var key1 = fetchRangeOffset(range.startOffset);
        var key2 = fetchRangeOffset(range.endOffset);

        return key1 == key2;
    }

    /**
     * 判断range的起始和结束向量是否相等
     * @param {*} range 
     * @returns 
     */
    this.equalsRangeOffset = function(range){
        return equalsRangeOffset(range);
    }

    /**
     * 拼接range
     * @param {*} range 
     */
    var fetchRangeOffset = function(offset){
        var key = "";

        for(var i in rangeOffsetPropsExt){
            if(rangeOffsetPropsExt[i] == "next" && offset.next){
                key += fetchRangeOffset(offset.next);
            }else if(offset[rangeOffsetPropsExt[i]] != null){
                key += offset[rangeOffsetPropsExt[i]];
            }
        }

        return key;
    }

    /**
     * 获取链表最后一个节点
     * @param {*} next 
     * @returns 
     */
    var getLastNext = function(next){
        if(next.next == null){
            return next;
        }
        return getLastNext(next.next);
    }

    /**
     * range是否可交换
     * @param {*} startOffset
     * @param {*} endOffset
     * @param {*} isExt
     * @returns 
     */
    var canExchange = function(startOffset, endOffset, isExt){
        var type = null;
        var props = isExt ? rangeOffsetPropsExt : rangeOffsetProps;

        for(var i in props){
            type = props[i];

            if(startOffset[type] > endOffset[type]){
                return true;
            }else if(startOffset[type] < endOffset[type]){
                return false;
            }
        }

        if(startOffset.next && endOffset.next){
            return canExchange(startOffset.next, endOffset.next, true);
        }

        return false;
    }

    /**
     * 页面定位
     * @param {*} sEvt 
     * @param {*} opt
     */
    this.locate = function(sEvt, opt){
        if(!sEvt.target || !sEvt.target.ref) return;

        if(!opt || !opt.closeBySelection){
            locateBySelection(sEvt, opt);
        }

        var sType = sEvt.target.ref._sType;

        switch(sType){
            case "sText":
                locateText.call(this, sEvt, opt);
                break;
            case "sParagraph":
                locateParagraph.call(this, sEvt, opt);
                break;
            case "sBreakline":
                locateBreakline.call(this, sEvt, opt);
                break;
            case "sLayer":
                locateLayer.call(this, sEvt, opt);
                break;
            case "sInputBegin":
            case "sInputEnd":
                locateInputArea.call(this, sEvt, opt);
                break;
        }
    }

    /**
     * 根据选择区域来定位
     * @param {*} sEvt 
     * @param {*} opt 
     */
    var locateBySelection = function(sEvt, opt){
        if(!sEvt || !sEvt.selection) return;
        
        var range = sEvt.selection.getRangeAt();
        if(range.collapsed) return;

        var lookResult = null;
        var isLeft = null;

        if(sEvt.keyName == "ArrowLeft" || sEvt.keyName == "ArrowUp"){
            isLeft = true;
        }else if(sEvt.keyName == "ArrowRight" || sEvt.keyName == "ArrowBottom"){
            isLeft = false;
        }

        if(isLeft !== null){
            lookResult = sEvt.pageList.lookup(
                sEvt.target.position, isLeft ? range.startOffset : range.endOffset);
        }

        if(lookResult != null){
            lookResultMergeToEvt(sEvt, lookResult);

            if(!opt){
                opt = {};
            }

            var next = ost.extractOffset(lookResult.offset, true);
            opt.locateContentIndex = next.contentIndex;

            delete sEvt.keyName;
        }

        if(opt && opt.clearSelection){
            opt.clearSelection();
        }
    }

    /**
     * 将lookup查找的结果和事件对象合并
     * @param {*} sEvt 
     * @param {*} lookResult 
     */
    this.lookResultMergeToEvt = function(sEvt, lookResult){
        lookResultMergeToEvt(sEvt, lookResult);
    }

    /**
     * 将lookup查找的结果和事件对象合并
     * @param {*} sEvt 
     * @param {*} lookResult 
     */
    var lookResultMergeToEvt = function(sEvt, lookResult){
        if(!sEvt.target){
            sEvt.target = {};
        }

        sEvt.target.ref = lookResult.ref;
        sEvt.target.boundRect = lookResult.boundRect;
        sEvt.target.isEndWithParagraph = lookResult.isEndWithParagraph;
        sEvt.target.isEndWithBreakline = lookResult.isEndWithBreakline;
        sEvt.target.isFirst = lookResult.isFirst;
        sEvt.target.isLast = lookResult.isLast;
        sEvt.target.text = lookResult.text;
        sEvt.target.rowRect = lookResult.rowRect;
        sEvt.target.position = lookResult.position;

        if(!sEvt.offset){
            sEvt.offset = {};
        }

        sEvt.offset.left = lookResult.boundRect.left;
        sEvt.offset.top = lookResult.boundRect.top;

        ost.mergeOffset(sEvt.target, lookResult.offset);
    }

    /**
     * 定位文本元素
     * @param {*} sEvt 事件对象
     * @param {*} opt 可选项
     * @returns 
     */
    var locateText = function(sEvt, opt) {
        var rect = sEvt.target.boundRect;

        //当前行的文本平均间隔(两端对齐、分散对齐)
        rect.letterSpacing = rect.letterSpacing ? rect.letterSpacing : 0;
        
        var left = 0;
        var top = 0;
        var height = 0;
        var width = 0;

        //当前元素
        var element = sEvt.target.ref;
        var font = painter.getStyle("font");

        //设置为当前元素字体
        painter.setStyle({font: element.getFontStyle(scale)});

        var inRange = false;
        var metrics = null;
        var textWidth = 0;
        var contentIndex = -1;

        if(opt && opt.locateFirst){
            metrics = painter.measureCurText(sEvt.target.text.substr(0, 1), element);
            textWidth = rect.letterSpacing + metrics.width;

            left = rect.left + textWidth;
            contentIndex = 0;

            delete opt.locateFirst;
        }else if(opt && opt.locateLast){
            var length = sEvt.target.text.length;

            metrics = painter.measureCurText(sEvt.target.text.substr(0, length - 1), element);
            textWidth = rect.letterSpacing * (length - 1) + metrics.width;

            left = rect.left + textWidth;
            contentIndex = length - 2;
            contentIndex = contentIndex < -1 ? -1 : contentIndex;

            delete opt.locateLast;
        }else if(opt && opt.locateContentIndex != null){
            metrics = painter.measureCurText(sEvt.target.text.substr(0, opt.locateContentIndex + 1), element);

            var len = opt.locateContentIndex + 1;

            len = sEvt.target.isLast ? len - 1 : len;
            len = len < 0 ? 0 : len;

            textWidth = rect.letterSpacing * len + metrics.width;
            left = rect.left + textWidth;
            contentIndex = opt.locateContentIndex;

            delete opt.locateContentIndex;
        }else if(sEvt.keyName && sEvt.keyName.indexOf("Arrow") > -1){
            var overflow = false;
            var option = {...opt};

            if(sEvt.keyName == "ArrowLeft"){
                contentIndex = updateContentIndexInLocate(sEvt);
                if(contentIndex < -1){
                    updateContentIndexInLocate(sEvt, true);
                    if(sEvt.target.isFirst){
                        updateRowIndexInLocate(sEvt);
                        sEvt.offset.left = rect.offsetLeft + 
                            sEvt.target.rowRect.left + sEvt.target.rowRect.width;
                        sEvt.offset.top = sEvt.target.rowRect.top - DRIFT_LEN;
                    }else{
                        sEvt.offset.left = rect.left - DRIFT_LEN;
                        sEvt.offset.top = sEvt.target.rowRect.top + DRIFT_LEN;
                        option.locateLast = true;
                    }
                    overflow = true;
                }
            }else if(sEvt.keyName == "ArrowRight"){
                contentIndex = updateContentIndexInLocate(sEvt, true);
                if(contentIndex >= sEvt.target.text.length){
                    updateContentIndexInLocate(sEvt);
                    if(sEvt.target.isLast){
                        updateRowIndexInLocate(sEvt, true);

                        sEvt.offset.left = rect.offsetLeft + sEvt.target.rowRect.left;
                        sEvt.offset.top = sEvt.target.rowRect.top + sEvt.target.rowRect.height + DRIFT_LEN;
                    }else{
                        sEvt.offset.left = rect.left + rect.width + 
                            rect.letterSpacing * sEvt.target.text.length + DRIFT_LEN;
                        sEvt.offset.top = sEvt.target.rowRect.top + DRIFT_LEN;
                        option.locateFirst = true;
                    }
                    overflow = true;
                }
            }else if(sEvt.keyName == "ArrowUp"){
                updateRowIndexInLocate(sEvt);
                sEvt.offset.top = sEvt.target.rowRect.top - DRIFT_LEN;
                overflow = true;
            }else if(sEvt.keyName == "ArrowDown"){
                updateRowIndexInLocate(sEvt, true);
                sEvt.offset.top = sEvt.target.rowRect.top + sEvt.target.rowRect.height + DRIFT_LEN;
                overflow = true;
            }

            //超出当前元素范围
            if(overflow){
                option.keyName = sEvt.keyName;
                //还原字体
                painter.setStyle({font: font});
                opt.relocate(sEvt, option);

                return;
            }else{
                opt.keyName = sEvt.keyName;
            }

            sEvt.caret.blur();

            metrics = painter.measureCurText(sEvt.target.text.substring(0, contentIndex + 1), element);

            if(sEvt.target.isLast && contentIndex == sEvt.target.text.length - 1){
                left = rect.left + rect.letterSpacing * contentIndex + metrics.width;
            }else{
                left = rect.left + rect.letterSpacing * (contentIndex + 1) + metrics.width;
            }

            sEvt.offset.left = left;
            sEvt.offset.top = sEvt.target.rowRect.top + DRIFT_LEN;
        } else {
            var middle = null;
            //遍历当前元素的文本，找出当前位置的文本
            for(var i = 0; i < sEvt.target.text.length; i++){
                left = sEvt.offset.left;
                metrics = painter.measureCurText(sEvt.target.text.substr(i, 1), element);
                textWidth = rect.letterSpacing + metrics.width;

                middle = rect.left + width + textWidth / 2;

                if(compareNumber(left, rect.left + width) >= 0 && 
                    compareNumber(left, middle) <= 0){
                    //在文本的前半部分
                    left = rect.left + width;
                    inRange = true;
                    contentIndex = i - 1;
                } else if(compareNumber(left, middle) > 0 && 
                    compareNumber(left, rect.left + width + textWidth) <= 0){
                    //在文本的后半部分
                    left = rect.left + width + textWidth;
                    inRange = true;
                    contentIndex = i;
                }

                //当前行第一个可见元素
                if(i == 0 && sEvt.target.isFirst){
                    if(sEvt.offset.left < rect.left + width + metrics.width / 2){
                        left = rect.left + width;
                        inRange = true;
                        contentIndex = i - 1;
                    }
                }

                //当前行最后一个可见元素
                if(i == sEvt.target.text.length - 1 && sEvt.target.isLast){
                    if(sEvt.offset.left > rect.left + width + metrics.width / 2){
                        left = rect.left + width + metrics.width;
                        inRange = true;
                        contentIndex = i;
                    }
                }

                if(inRange){
                    break;
                }

                width = rect.letterSpacing * (i + 1) + 
                    painter.measureCurText(sEvt.target.text.substr(0, i + 1), element).width;
            }

            if(!inRange){
                left = rect.left;
            }
        }

        //还原字体
        painter.setStyle({font: font});

        updateContentIndexInLocate(sEvt, null, contentIndex);

        //如果和前一个元素交界
        if(contentIndex == -1 && 
            !sEvt.target.isFirst && 
            opt && opt.relocate){

            sEvt.offset.left = rect.left - DRIFT_LEN;

            opt.relocate(sEvt, {
                redirect: true,
                style: {
                    fontSize: element.getFontStyle(scale)
                },
                mergeOffset: opt.mergeOffset
            });

            return;
        }
        //如果到达当前行元素末尾
        else if(contentIndex == sEvt.target.text.length - 1 &&
            sEvt.target.isLast &&
            opt && (
                (opt.keyName == "ArrowRight" && 
                    !sEvt.target.isEndWithParagraph &&
                    !sEvt.target.isEndWithBreakline
                ) || 
                (opt.keyName == "ArrowLeft" &&
                !sEvt.target.isEndWithParagraph &&
                !sEvt.target.isEndWithBreakline)
            ) && !opt.notSkipEnd){

            sEvt.keyName = opt.keyName;
            locateText.call(this, sEvt, opt);

            return;
        }

        if(!opt || !opt.notDoSelection){
            doSelection.call(this, sEvt);
        }

        if(opt && opt.mergeOffset){
            opt.mergeOffset(()=>{
                doSelection.call(this, sEvt);
            });
        }

        sEvt.offset.left = left;

        left = sEvt.baseOffset.left + left / sEvt.ratio;
        top = sEvt.baseOffset.top + rect.top / sEvt.ratio;

        height = rect.height / sEvt.ratio;

        rect = {
            left: left,
            top: top,
            width: rect.width,
            height: height
        };

        sEvt.locateRect = rect;

        if(!opt || !opt.notMoveCaret){
            sEvt.caret.moveTo(rect);
            sEvt.textInput.moveTo({
                left: rect.left,
                top: rect.top + rect.height,
                height: rect.height
            });
    
            sEvt.layerResize.blur();
        }
    }

    /**
     * 比较数字
     * @param {*} num1 比较数
     * @param {*} num2 被比较数
     */
    var compareNumber = function(num1, num2){
        num1 = parseFloat(num1.toFixed(4));
        num2 = parseFloat((num2 + 0.0001).toFixed(4));

        return num1 > num2 ? 1 : num1 < num2 ? -1 : 0;
    }

    /**
     * 定位层元素
     * @param {*} sEvt 
     * @param {*} 可选项 
     */
    var locateLayer = function(sEvt, opt) {
        if(sEvt.target && sEvt.target.ref.style.position == "absolute"){
            locateLayerForAbsolute(sEvt, opt);
            return;
        }

        var rect = sEvt.target.boundRect;
        var left = rect.left;
        var width = rect.width;
        var edge = null;
        var contentIndex = -1;

        rect.letterSpacing = rect.letterSpacing ? rect.letterSpacing : 0;

        if(opt && opt.locateFirst){
            edge = "right";
            contentIndex = 0;
            left = rect.left + rect.width + (sEvt.target.isLast 
                ? 0
                : rect.letterSpacing);

            delete opt.locateFirst;
        }else if(opt && opt.locateLast){
            edge = "left";
            contentIndex = -1;
            left = rect.left;

            delete opt.locateLast;
        }else if(opt && opt.locateContentIndex != null){
            left = rect.left;
            contentIndex = opt.locateContentIndex;

            delete opt.locateContentIndex;
        }else if(sEvt.keyName){
            var overflow = false;
            var option = {...opt};

            if(sEvt.keyName == "ArrowLeft"){
                if(sEvt.layerResize.isActive()){
                    updateContentIndexInLocate(sEvt, null, 0);
                }

                edge = "left";
                contentIndex = updateContentIndexInLocate(sEvt);
                if(contentIndex < -1){
                    updateContentIndexInLocate(sEvt, true);
                    if(sEvt.target.isFirst){
                        updateRowIndexInLocate(sEvt);
                        sEvt.offset.left = sEvt.target.rowRect.left + sEvt.target.rowRect.width;
                        sEvt.offset.top = sEvt.target.rowRect.top - DRIFT_LEN;
                    }else{
                        sEvt.offset.left = rect.left - DRIFT_LEN;
                        sEvt.offset.top = sEvt.target.rowRect.top + DRIFT_LEN;
                        option.locateLast = true;
                    }
                    overflow = true;
                }
            }else if(sEvt.keyName == "ArrowRight"){
                if(sEvt.layerResize.isActive()){
                    updateContentIndexInLocate(sEvt, null, -1);
                }

                edge = "right";
                contentIndex = updateContentIndexInLocate(sEvt, true);
                if(contentIndex >= 1){
                    updateContentIndexInLocate(sEvt);
                    if(sEvt.target.isLast){
                        updateRowIndexInLocate(sEvt, true);
                        sEvt.offset.left = sEvt.target.rowRect.left;
                        sEvt.offset.top = sEvt.target.rowRect.top + sEvt.target.rowRect.height + DRIFT_LEN;
                    }else{
                        sEvt.offset.left = rect.left + 
                            rect.width + rect.letterSpacing * (contentIndex + 1) + DRIFT_LEN;
                        sEvt.offset.top = sEvt.target.rowRect.top + DRIFT_LEN;
                        option.locateFirst = true;
                    }
                    overflow = true;
                }else{
                    left = rect.left + rect.width + rect.letterSpacing * (contentIndex + 1);
                }
            }else if(sEvt.keyName == "ArrowUp"){
                updateRowIndexInLocate(sEvt);
                sEvt.offset.top = sEvt.target.rowRect.top - DRIFT_LEN;
                overflow = true;
            }else if(sEvt.keyName == "ArrowDown"){
                updateRowIndexInLocate(sEvt, true);
                sEvt.offset.top = sEvt.target.rowRect.top + sEvt.target.rowRect.height + DRIFT_LEN;
                overflow = true;
            }

            //超出当前元素范围
            if(overflow){
                option.keyName = sEvt.keyName;
                opt.relocate(sEvt, option);
                return;
            }else{
                opt.keyName = sEvt.keyName;
                sEvt.offset.left = left;
                sEvt.offset.top = sEvt.target.rowRect.top + DRIFT_LEN;
            }

            sEvt.caret.blur();
        }else{
            if(sEvt.offset.left < rect.left){
                edge = "left";
                contentIndex = -1;
            } else if(sEvt.offset.left >= rect.left && 
                sEvt.offset.left <= rect.left + rect.width / 2){
                //在元素的前半部分
                contentIndex = -1;
            } else if(sEvt.offset.left > rect.left + rect.width / 2 && 
                sEvt.offset.left <= rect.left + rect.width){
                //在元素的后半部分
                contentIndex = 0;
                width += (sEvt.target.isLast ? 0 : rect.letterSpacing);
                left = rect.left + width;
            } else if(sEvt.offset.left > rect.left + rect.width){
                edge = "right";
                contentIndex = 0;
                width += (sEvt.target.isLast ? 0 : rect.letterSpacing);
                left = rect.left + width;
            }
        }

        updateContentIndexInLocate(sEvt, null, contentIndex);

        //如果和前一个元素交界
        if(contentIndex == -1 && 
            sEvt.eventType != "mousedown" &&
            !sEvt.target.isFirst && opt && opt.relocate){
            
            sEvt.offset.left = rect.left - DRIFT_LEN;
            opt.relocate(sEvt);

            return;
        }
        //如果到达当前行元素末尾
        else if(contentIndex == 0 &&
            sEvt.target.isLast &&
            opt && ((opt.keyName == "ArrowRight" && !sEvt.target.isEndWithParagraph) || 
            opt.keyName == "ArrowLeft")){

            sEvt.keyName = opt.keyName;
            locateLayer.call(this, sEvt, opt);

            return;
        }

        if(!opt || !opt.notDoSelection){
            doSelection.call(this, sEvt);
        }

        if((sEvt.eventType == "mouseup" || 
            (!edge && sEvt.eventType == "mousedown")) && 
            (!opt || !opt.redirect)){

            if(isDesignView(setting.docMode)){
                rect = {
                    left: sEvt.baseOffset.left + rect.left / sEvt.ratio - 1,
                    top: sEvt.baseOffset.top + rect.top / sEvt.ratio - 1,
                    width: rect.width / sEvt.ratio,
                    height: rect.height / sEvt.ratio
                }
    
                sEvt.layerResize.moveTo(rect);
            }

            sEvt.caret.blur(true);
            sEvt.textInput.blur();
        }else{
            rect = {
                left: sEvt.baseOffset.left + left / sEvt.ratio,
                top: sEvt.baseOffset.top + rect.top / sEvt.ratio,
                width: width / sEvt.ratio,
                height: rect.height / sEvt.ratio
            }

            sEvt.locateRect = rect;

            if(!opt || !opt.notMoveCaret){
                if(edge == "right"){
                    sEvt.caret.moveTo(rect);
                    sEvt.textInput.moveTo({
                        left: rect.left,
                        top: rect.top + rect.height,
                        height: rect.height
                    });
                }else{
                    sEvt.caret.moveTo(rect);
                    sEvt.textInput.moveTo({
                        left: rect.left,
                        top: rect.top + rect.height,
                        height: rect.height
                    });
                }
    
                sEvt.layerResize.blur();
            }
        }
    }

    /**
     * 定位绝对定位层元素
     * @param {*} sEvt 
     * @param {*} opt 
     */
    var locateLayerForAbsolute = function(sEvt, opt){
        if(isDesignView(setting.docMode)){
            var layer = sEvt.target.ref;
            rect = {
                left: sEvt.baseOffset.left + parseFloat(layer.style.left) / sEvt.ratio - 1,
                top: sEvt.baseOffset.top + parseFloat(layer.style.top) / sEvt.ratio - 1,
                width: parseFloat(layer.style.width) / sEvt.ratio,
                height: parseFloat(layer.style.height) / sEvt.ratio
            }

            sEvt.layerResize.moveTo(rect);
        }
    }

    /**
     * 是否是设计视图
     * @param {*} mode 
     * @returns 
     */
    var isDesignView = function(mode){
        return mode == ssDict.sDocMode.DESIGN;
    }

    /**
     * 定位输入域
     * @param {*} sEvt 
     * @param {*} 可选项 
    */
    var locateInputArea = function(sEvt, opt) {
        var rect = sEvt.target.boundRect;
        var left = rect.left;
        var width = rect.width;
        var edge = null;
        var contentIndex = -1;

        rect.letterSpacing = rect.letterSpacing ? rect.letterSpacing : 0;

        if(opt && opt.locateFirst){
            edge = "right";
            contentIndex = 0;
            left = rect.left + rect.width + (sEvt.target.isLast 
                ? 0
                : rect.letterSpacing);

            delete opt.locateFirst;
        }else if(opt && opt.locateLast){
            edge = "left";
            contentIndex = -1;
            left = rect.left;

            delete opt.locateLast;
        }else if(opt && opt.locateContentIndex != null){
            left = rect.left;
            contentIndex = opt.locateContentIndex;

            delete opt.locateContentIndex;
        }else if(sEvt.keyName){
            var overflow = false;
            var option = {...opt};

            if(sEvt.keyName == "ArrowLeft"){
                edge = "left";
                contentIndex = updateContentIndexInLocate(sEvt);
                if(contentIndex < -1){
                    updateContentIndexInLocate(sEvt, true);
                    if(sEvt.target.isFirst){
                        updateRowIndexInLocate(sEvt);
                        sEvt.offset.left = sEvt.target.rowRect.left + sEvt.target.rowRect.width;
                        sEvt.offset.top = sEvt.target.rowRect.top - DRIFT_LEN;
                    }else{
                        sEvt.offset.left = rect.left - DRIFT_LEN;
                        sEvt.offset.top = sEvt.target.rowRect.top + DRIFT_LEN;
                        option.locateLast = true;
                    }
                    overflow = true;
                }
            }else if(sEvt.keyName == "ArrowRight"){
                edge = "right";
                contentIndex = updateContentIndexInLocate(sEvt, true);
                if(contentIndex >= 1){
                    updateContentIndexInLocate(sEvt);
                    if(sEvt.target.isLast){
                        updateRowIndexInLocate(sEvt, true);
                        sEvt.offset.left = sEvt.target.rowRect.left;
                        sEvt.offset.top = sEvt.target.rowRect.top + sEvt.target.rowRect.height + DRIFT_LEN;
                    }else{
                        sEvt.offset.left = rect.left + 
                            rect.width + rect.letterSpacing * (contentIndex + 1) + DRIFT_LEN;
                        sEvt.offset.top = sEvt.target.rowRect.top + DRIFT_LEN;
                        option.locateFirst = true;
                    }
                    overflow = true;
                }else{
                    left = rect.left + rect.width + rect.letterSpacing * (contentIndex + 1);
                }
            }else if(sEvt.keyName == "ArrowUp"){
                updateRowIndexInLocate(sEvt);
                sEvt.offset.top = sEvt.target.rowRect.top - DRIFT_LEN;
                overflow = true;
            }else if(sEvt.keyName == "ArrowDown"){
                updateRowIndexInLocate(sEvt, true);
                sEvt.offset.top = sEvt.target.rowRect.top + sEvt.target.rowRect.height + DRIFT_LEN;
                overflow = true;
            }

            //超出当前元素范围
            if(overflow){
                option.keyName = sEvt.keyName;
                opt.relocate(sEvt, option);
                return;
            }else{
                opt.keyName = sEvt.keyName;
                sEvt.offset.left = left;
                sEvt.offset.top = sEvt.target.rowRect.top + DRIFT_LEN;
            }

            sEvt.caret.blur();
        }else{
            if(sEvt.offset.left < rect.left){
                edge = "left";
                contentIndex = -1;
            } else if(sEvt.offset.left >= rect.left && 
                sEvt.offset.left <= rect.left + rect.width / 2){
                //在元素的前半部分
                contentIndex = -1;
            } else if(sEvt.offset.left > rect.left + rect.width / 2 && 
                sEvt.offset.left <= rect.left + rect.width){
                //在元素的后半部分
                contentIndex = 0;
                width += (sEvt.target.isLast ? 0 : rect.letterSpacing);
                left = rect.left + width;
            } else if(sEvt.offset.left > rect.left + rect.width){
                edge = "right";
                contentIndex = 0;
                width += (sEvt.target.isLast ? 0 : rect.letterSpacing);
                left = rect.left + width;
            }
        }

        updateContentIndexInLocate(sEvt, null, contentIndex);

        //如果和前一个元素交界
        if(contentIndex == -1 && 
            sEvt.eventType != "mousedown" &&
            !sEvt.target.isFirst && opt && opt.relocate){
            
            sEvt.offset.left = rect.left - DRIFT_LEN;
            opt.relocate(sEvt);

            return;
        }
        //如果到达当前行元素末尾
        else if(contentIndex == 0 &&
            sEvt.target.isLast &&
            opt && ((opt.keyName == "ArrowRight" && !sEvt.target.isEndWithParagraph) || 
            opt.keyName == "ArrowLeft")){

            sEvt.keyName = opt.keyName;
            locateLayer.call(this, sEvt, opt);

            return;
        }

        if(!opt || !opt.notDoSelection){
            doSelection.call(this, sEvt);
        }

        rect = {
            left: sEvt.baseOffset.left + left / sEvt.ratio,
            top: sEvt.baseOffset.top + rect.top / sEvt.ratio,
            width: width / sEvt.ratio,
            height: rect.height / sEvt.ratio
        }

        sEvt.locateRect = rect;

        if(!opt || !opt.notMoveCaret){
            if(edge == "right"){
                sEvt.caret.moveTo(rect);
                sEvt.textInput.moveTo({
                    left: rect.left,
                    top: rect.top + rect.height,
                    height: rect.height
                });
            }else{
                sEvt.caret.moveTo(rect);
                sEvt.textInput.moveTo({
                    left: rect.left,
                    top: rect.top + rect.height,
                    height: rect.height
                });
            }
        }
    }

    /**
     * 定位段落元素
     * @param {*} sEvt 
     * @param {*} opt 
     */
    var locateParagraph = function(sEvt, opt) {
        doSelection.call(this, sEvt);

        //段落元素之前的元素目标
        if(sEvt.target.prevTarget){
            sEvt.target = sEvt.target.prevTarget;
            //不是选择状态
            if(sEvt.selection.getRangeAt().collapsed){
                delete opt.keyName;
                this.locate(sEvt, opt);
            }else{
                opt = opt ? opt : {};
                opt.locateContentIndex = sEvt.target.text
                    ? sEvt.target.text.length - 1
                    : 0;
                opt.notDoSelection = true;
                this.locate(sEvt, opt);
            }
        }
    }

    /**
     * 定位换行元素
     * @param {*} sEvt 
     * @param {*} opt 
     */
    var locateBreakline = function(sEvt, opt) {
        doSelection.call(this, sEvt);

        //换行元素之前的元素目标
        if(sEvt.target.prevTarget){
            sEvt.target = sEvt.target.prevTarget;
            //不是选择状态
            if(sEvt.selection.getRangeAt().collapsed){
                delete opt.keyName;
                this.locate(sEvt, opt);
            }else{
                opt = opt ? opt : {};
                opt.locateContentIndex = sEvt.target.text
                    ? sEvt.target.text.length - 1
                    : 0;
                opt.notDoSelection = true;
                this.locate(sEvt, opt);
            }
        }
    }

    /**
     * 更新事件目标的行号
     * @param {*} sEvt 事件对象 
     * @param {*} plus true 递增1 false递减1
     */
    var updateRowIndexInLocate = function(sEvt, plus){
        for(var next = sEvt.target; next != null; next = next.next){
            if(next.next) continue;
            next.rowIndex += plus ? 1 : -1;
            break;
        }
        return next.rowIndex;
    }

    /**
     * 更新事件目标的内容序号
     * @param {*} sEvt 事件对象 
     * @param {*} plus true 递增1 false递减1
     * @param {*} contentIndex 可选，直接指定内容序号，优先级高于plus
     */
    var updateContentIndexInLocate = function(sEvt, plus, contentIndex){
        for(var next = sEvt.target; next != null; next = next.next){
            if(next.next) continue;
            if(contentIndex != null){
                next.contentIndex = contentIndex;
            }else{
                next.contentIndex += plus ? 1 : -1;
            }
            break;
        }
        return next.contentIndex;
    }

    /**
     * 将当前元素从元素链中脱离
     * @param {*} element 
     */
    this.unlinkElement = function(element){
        return unlinkElement(element);
    }

    /**
     * 将当前元素从元素链中脱离
     * @param {*} element 
     */
    var unlinkElement = function(element){
        if(element.__boundRect) return false;

        linkElement(element.__prevSibling, element.__nextSibling);
        element.__prevSibling = null;
        element.__nextSibling = null;

        return true;
    }

    /**
     * 链接两个元素，形成双向链表
     * @param {*} prevElement 
     * @param {*} nextElement 
     */
    this.linkElement = function(prevElement, nextElement){
        linkElement(prevElement, nextElement);
    }

    /**
     * 链接两个元素，形成双向链表
     * @param {*} prevElement 
     * @param {*} nextElement 
     */
    var linkElement = function(prevElement, nextElement){
        if(!prevElement || !nextElement || prevElement === nextElement) return;

        prevElement.__nextSibling = nextElement;
        nextElement.__prevSibling = prevElement;
    }
}